bash: ‘\n’ in read file

py2app で分割で作っている Python ファイルを扱う手段がわからない。
ならば合体スクリプトを作って単体にしてしまえばいいんでね?

目印に #begin, #end みたいなのを書いてその中間だけを取り出せば簡単そう。
ということで早速シェルスクリプトを書いてみた。

##!/bin/sh

ifs=$IFS
IFS=$'\n'

for filename in *.py; do
    while read -r line; do
        [[ $line =~ "#end" ]] && break
        [[ $begin = begin ]] && lines+="$line\n"
        [[ $line =~ "#begin" ]] && begin=begin
    done < $filename
    begin=""
done

echo -e $lines

IFS=$ifs

のですけど。。。

#!/usr/bin/env python3

#begin

class TestClass():
    def __init__(self):
        print('hello\nworld')

#end
TestClass()

こんなファイルで試すと。

class TestClass():
    def __init__(self):
        print('hello
world')

えぇ。。。

ソースコード中の \n まで改行とみなされてしまうのカヨ!
ちなみに -r 無しだと hellonworld になるのでもっと注意。
cat ならイケるかな。

##!/bin/sh

ifs=$IFS
IFS=$'\n'

for filename in *.py; do
    for line in `cat $filename`; do
        [[ $line =~ "#end" ]] && break
        [[ $begin = begin ]] && lines+="$line\n"
        [[ $line =~ "#begin" ]] && begin=begin
    done
    begin=""
done

echo -e $lines

IFS=$ifs

同じだ。。。

#!/usr/bin/env python3

import os

lines = []
begin = ''

for filename in [s for s in os.listdir() if s.endswith('.py')]:
    with open(filename) as f:
        for s in f.read().split('\n'):
            if '#end' in s: break;
            elif begin == 'begin': lines.append(s)
            elif '#begin' in s: begin = 'begin'
    begin = ''

print('\n'.join(lines))

python 等なら問題ない。

connect.py みたいなファイルを用意してシェルから呼ぶことにするか。
シェルってほんとに色々と困ったちゃん。