sed
シンプルで迅速なので、サンプルデータファイルを処理するために使用します。sed
これには、行番号ファイルを適切なスクリプトに変換するメカニズムが必要です。これを行うには多くの方法があります。
1 つの方法は、一連の行番号をスクリプトsed
に変換するために使用します。sed
すべてが標準出力に出力される場合、これは簡単なことです。出力を別のファイルに移動する必要があるため、行番号ファイルの各行に行番号が必要です。行番号を与える 1 つの方法は、nl
コマンドです。別の可能性は、を使用することpr -n -l1
です。同じsed
コマンド ラインが両方で機能します。
nl linenumbers.txt |
sed 's/ *\([0-9]*\)[^0-9]*\([0-9]*\)|\([0-9]*\)/\2,\3w file\1.txt/'
指定されたデータ ファイルに対して、次が生成されます。
345,789w > file1.txt
999,1056w > file2.txt
1522,1366w > file3.txt
3523,3562w > file4.txt
別のオプションは、スクリプトをawk
生成することです。sed
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt
のバージョンでsed
標準入力からスクリプトを読み取ることができる場合-f -
(GNUでは可能sed
ですが、BSDでは不可能です)、行番号ファイルをオンザフライでスクリプトにsed
変換し、それを使用してサンプル データを解析できます。sed
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f - sample.data
システムが をサポートしている場合は/dev/stdin
、次のいずれかを使用できます。
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f /dev/stdin sample.data
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f /dev/fd/0 sample.data
それができない場合は、明示的なスクリプト ファイルを使用します。
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt > sed.script
sed -n -f sed.script sample.data
rm -f sed.script
厳密には、一時ファイル名が一意 ( mktemp
) であり、スクリプトが中断された場合でも削除される( ) ように対処する必要がありますtrap
。
tmp=$(mktemp sed.script.XXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt > $tmp
sed -n -f $tmp sample.data
rm -f $tmp
trap 0
最後trap 0
に、スクリプトが正常に終了できるようにします。省略すると、スクリプトは常にステータス 1 で終了します。
Perl と Python は無視しました。どちらも単一のコマンドでこれに使用できます。ファイル管理は面倒なので、使用するsed
方が簡単に思えます。just を使用することもできますawk
。最初awk
のスクリプトでスクリプトawk
を作成して負荷の高い作業を実行するか (上記の簡単な拡張)、単一のawk
プロセスで両方のファイルを読み取って必要な出力を生成します (より困難ですが、不可能ではありません)。
少なくとも、これは、この仕事を行う方法がたくさんあることを示しています。これが 1 回限りの演習である場合、どちらを選択するかは実際にはあまり重要ではありません。これを繰り返し行う場合は、好きなメカニズムを選択してください。パフォーマンスが気になる場合は、測定してください。行番号をコマンド スクリプトに変換するコストは、ほとんどありません。コマンド スクリプトを使用してサンプル データを処理するのに時間がかかります。sed
私はその時点で優れていると期待しています。私はそれを確認するために測定していません。