同じディレクトリに複数のファイルがあるので、15日から20日までの連続した間隔で特定の行を印刷したいと思います。
単一ファイルの場合は機能しますhead -n20 file.txt | tail -n6
が、ワイルドカードパターンで機能させるにはどうすればよいですか?例えば、そのディレクトリ内のすべてのtxtファイルについて*.txt
?
head -n20 *.txt | tail -n6 # this only crops results of head -n20
編集1:解決策も知っていますが、for
ワイルドカードでも機能する統合された方法で複数のタスクのパイプラインを定義する方法を学びたいと思います。
psには、wildcards==> file.txt <==
と組み合わせるときに提供されるような標準ヘッダーがあるかもしれませんが、これはあまりにも多くを必要とします。head
tail
ppsはUbuntuを使用していますが、UNIX全体のアプローチが優れています。
答え1
この一行はどうですか?
for f in *.txt; do echo -e "\n==> $f <=="; head -n 20 "$f" | tail -n 6; done
現在のディレクトリで実行されている場合は、globを使用して.txt
すべて*.txt
のファイルを繰り返し、ヘッダーを印刷し、各ファイルに対してヘッドとテールを実行します。
答え2
参考にしてください。基準head
複数のファイル名を引数として使用し、これらの==> filename <==
ヘッダーを出力できます。基準tail
1つのファイル名のみを引数として使用できます。複数のファイル名が渡された場合、動作は指定されません。
ここでは、シェルループの代わりに次のコマンドを使用できますgawk
。
gawk 'BEGINFILE{print sep"==> "substr(FILENAME, 3)" <=="; sep = "\n"}
FNR >= 15
FNR == 20 {nextfile}' ./*.txt
これを関数に置き換えることができます。
linerange() (
min=$1 max=$2
shift 2
exec gawk -v min="$min" -v max="$max" -e '
BEGINFILE{print sep"==> "FILENAME" <=="; sep = "\n"}
FNR > max {nextfile}
FNR >= min' -E /dev/null "$@"
)
それから:
linerange 15 20 *.txt
gawk
、他の質問と同様に、awk
フォームのパラメータはvar=value
入力ファイル名ではなく変数割り当てとして扱われます。これは、一部の.txt
ファイルが正しく機能しない場合(または...foo=bar.txt
などのより迷惑な副作用が発生する可能性があります)を意味します。ARGC=0.txt
ORS=.txt
最初のケースではプレフィックス./
(後で削除する)を使用してこの問題を解決しsubstr(FILENAME, 3)
、2番目のケースでは(空のファイル:/ dev / nullを渡しますが、パラメータを使用して-E
も割り当ては処理されません)。-E