私のパスには以下が含まれます。
/home/user/data/foo/test_foo.gz
/home/user/data/bar/test_bar.gz
/home/user/data/fub/test_fub.gz
and so on...
すべての.gzファイルの3行目を印刷しようとしています。
zcat /home/user/data/*/test_*.gz | sed -n '3p' > results
しかし、これは3行目だけを表示します。test_foo.gz
答え1
sed
はい、送信されるストリームがこれらのファイルの圧縮されていないコンテンツの組み合わせであることだけがわかるzcat
ためです。cat
gz
sed
ここでは、各ファイルに対して1つずつ実行する必要があります。
for file in /home/user/data/*/test_*.gz; do
{ zcat | sed '3!d;q'; } < "$file"
done > result
ここでは、3行目以降に終了するためにsed '3!d;q'
forを使用するため、ファイル全体の解凍が完了する前に中断できます。sed
zcat
{ a | b; } < file
開くことができない場合は実行されないか、a
両方が実行されていないことを確認してくださいb
。file
ではa < file | b
実行をa
スキップしますが、ではスキップしますb
。 In(ファイル自体を開くことができるコマンドa file | b
の場合)は、ファイルを開くことができるかどうかに関係なく開始されます。a
a
b
zgrep
少なくともDebianでは、次のようにすることもできます。
GREP=sed zgrep '3!d;q' /home/user/data/*/test_*.gz
zgrep
実際には引数に従って実行されるシェルスクリプトがあります(zcat -f | $GREP
そのオプションを使用しない限り、ファイル名の前にusingを付けます。ただし、オプションがに渡されサポートされていないため、ここでwithを使用することは機能しません)。sed
-h
-h
GREP=sed
$GREP
sed
答え2
あなたのパイプライン、
zcat /home/user/data/*/test_*.gz | sed -n '3p' > results
このパターンに一致するすべてのファイルの内容をストリームとして抽出し、そこから3行目を抽出します。
3行目のインポート各ファイルの、あなたはそれらを繰り返す必要があります:
for pathname in /home/user/data/*/test_*.gz; do
zcat "$pathname" | sed -n 3p
done >results
zcat
これは各ファイルに対して一度、そしてsed
一度(パターンが一致すると仮定)呼び出されます。
答え3
次のコマンドで完了しますfind
。
find path -type f -iname "*.gz" -exec bash -c "zcat {}|sed -n 'p'" \; >>results.txt