この形式のデータファイルがあります
1 4
2 0
2 3
3 5
5 3
8 12
2 3
3 5
5 3
0 -1
2 4
33 3
ファイルには12行があり、それぞれ3行の4つの連続ブロックとして解釈する必要があります。たとえば、3番目のブロックは
2 3
3 5
5 3
mからnまでの各ブロックからiからjまでの行を抽出してLinuxでファイルに出力する方法は?
たとえば、、、、の場合、i=2
目的のj=3
結果m=1
はn=3
次のようになります。
2 0
2 3
5 3
8 12
3 5
5 3
ありがとうございます。
ベストアンサー1
次のawk
プログラムは、次のことを行う必要があります。
awk -v bs=3 -v i=2 -v j=3 -v m=1 -v n=3 '(FNR/bs>m-1) && (FNR/bs<=n) && ((FNR-1)%bs>=i-1) && ((FNR-1)%bs<j)' input.txt
これにより、キーデータがawk
変数としてプログラムにインポートされます。
- 変数としてのブロックサイズ
bs
- 開始および終了ブロック番号を変数として使用
m
します。n
- 開始行と終了行番号を変数として使用
i
します。j
これは、非ゼロと評価された「ルール」ブロックの外側のすべての条件が現在の行を印刷するように指示するawk
ロジックを使用します。true
awk
FNR
印刷は、各ファイルの行カウンタを表す自動変数に基づいています。あなたの要件は、基本的に数字をブロックサイズで割ってブロック番号を識別し、FNR
計算モジュラスでブロック内の行を識別しFNR
(便宜上、ゼロから始めて使用する)印刷したい行にのみ適用されます。FNR-1
true
修正する
時間のかかる作業をできるだけ避けることで、プログラムのスピードを上げることができます。これを行うには、次のようにプログラムを変更します。
awk ... 'BEGIN{first=bs*(m-1)+1; last=bs*n}
FNR<first{next}
FNR>last{exit}
((FNR-1)%bs>=i-1) && ((FNR-1)%bs<j)' input.txt
これにより、最初に考慮すべき最初の行と最後の行が決定されます。
- 現在の行番号が最初のブロックの先頭より前の場合は、すぐに次の行にジャンプして印刷するかどうかを「きめ細かく」確認するための計算と比較は行われません。
- 同様に、現在の行番号が考慮すべき最後のブロックを超えると、プログラムは直ちに終了します。
- 「関心領域」内にある場合にのみ、印刷する行を確認するために算術演算が実行されます。
これにより、計算作業を最小限に抑えることができます。
GNUバリアントを使用awk
して複数の入力ファイルを引数として指定した場合は、プログラムを終了するのではなく、次のファイルに移動するために代わりnextfile
に使用してください。exit