ファイルストリームをstdin
より小さな部分に分割し、各部分をスクリプトに渡す方法、
次のような大容量ファイルがありますstdin
。
␁HeadingHere
abcd
abcd
␁Different Title
bcde
bcde
{a lot longer}
␁Different again!
cdef
cdef
この部分を渡す方法を探しています。./script.sh
これは次のタスクをシミュレートします。
cat <<EOF | ./script.sh
␁HeadingHere
abcd
abcd
EOF
cat <<EOF | ./script.sh
␁Different Title
bcde
bcde
{a lot longer}
EOF
cat <<EOF | ./script.sh
␁Different again!
cdef
cdef
EOF
各部分は分解して識別できます␁
。
xargs
似たようなものを使ってやろうと思ったのですが、xargs -d '\01' -n1 echo
偶然出会いました。xargs: argument line too long
理想的には、スクリプトは以下と互換性がposix
あります。
答え1
これらの部分を別々のファイルに分割して1つずつ処理できます。これはoutfile.1
次の結果をもたらします。
awk '/^␁/ { count++ } { print > "outfile." count } ' < file
または、awk
部品を1つずつコマンドにパイプすることもできます。
awk 'BEGIN {command = "./script.sh"} /^␁/ { close(command) }
{ print | command } ' < file
私はタイトルを始めるために上で文字通りU + 2401表記を使用しました。なぜなら、それはコピーペーストを介して得たからです。コマンドラインで使用したので、\01
これらのコマンドがある場合は、xargs
コードでSOHチルダを実際のSTART OF HEADINGに変更することもできます。\001
awk
SOHに設定することもできますが、RS
ここではレコードの先頭にSOHがあり、最後にレコード区切りawk
文字が見つかると予想しているため、これは完全には適切ではありません。
答え2
ソースファイルに空の行(2つの連続した改行)がない場合は、␁
sedを使用して各空の行を2つの改行に変換できます。これにより、各レコードの区切り文字で空行を含むファイル(またはストリーム)が生成されます。その後、awk(空のRSを使用)は、各「空行」で区切られたファイル(ストリーム)を「レコード」に分割できます。
説明は複雑に見えるかもしれませんが、コードを見てください。
sed 's/␁/\n\n/g' file | awk -v RS='' -vf="./script" '{print|f;close(f)}'
実際にバイト値が0x01の文字を変換する必要がある場合は、sedコマンドを上書きしてください␁
。\x01