日別アーカイブ: 2019/02/24

bash: ‘\n’ in read file

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##!/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

のですけど。。。

1
2
3
4
5
6
7
8
9
10
#!/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 ならイケるかな。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##!/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

同じだ。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/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 みたいなファイルを用意してシェルから呼ぶことにするか。
シェルってほんとに色々と困ったちゃん。