私は多くのgzファイルを持っており、解凍したバージョンにはパターンが含まれていますA
。B=1
(これらは明らかにA
最初に出てくる別の行にあります。)
A
現在行とB=1
現在行の内容を提供するコマンドを作成したいと思います。または少なくともA
その間に何かがありますB=1
。
入力ファイル1:
..A ...
...
...B=0..
...
入力ファイル2:
..A ...
...
...B=1..
...
私のコマンドは必ずfile2の出力A ....B=1
と何もないファイル1の場合。
同様のことをしましたが、期待どおりに動作しませんでした。
find . -name \*.gz -print0 | xargs -0 zcat | sed -n -e '/A/,/B=1/p'
ここで問題は何ですか?
ベストアンサー1
今は圧縮を無視してみましょう。A
との間の行を出力しようとしていますB=1
が、両方が存在する場合にのみ可能です。あなたが使用しているのはそれを見るとすぐに出力を開始して確認しないので、そうしませんsed
。私たちはそれが見つかるまですべてを保持するために保持バッファを使用できますが、私はそれがより快適です。だからここにあります:A
B=1
sed
B=1
awk
$ echo -en 'not this\nA\nthis\nB=1\nnot this\n' |
awk '/A/ {save=1} save {data = data $0 ORS} /B=0/ {save=0; data=""} /B=1/ {save=0; printf "%s", data; data=""} '
A
this
B=1
このB=0
ルールは印刷しないでくださいブロックを処理します。
その後、圧縮と複数のファイルを処理します。あなたがしたことはfind
+うまくいきますが、xargs
いくつかのファイルに部分ブロック(A
何もありません)がある可能性がある場合は、B
ファイルを一緒にリンクすると問題が発生する可能性があります。これが真ではないと仮定すると、最後にawkを置くことができます。
$ find . -name foo\*.gz -print0 | xargs -0 zcat | \
awk '/A/ {s=1} s {d = d $0 ORS} /B=0/ {s=0; d=""}
/B=1/ {s=0; printf "%s", d; d=""} '
本当に部分チャンクを処理する必要がある場合は、各ファイルを個別に処理する必要があります。
$ find . -name foo\*.gz -print0 | xargs -0 sh -c '
for f; do zcat "$f" | awk '\''/A/ {s=1} s {d = d $0 ORS}
/B=0/ {s=0; d=""} /B=1/ {s=0; printf "%s", d; d=""} '\''; done' sh
引用は不便なので、awk
スクリプトにはおそらく独自のファイルが必要です。
または単にシェル(Bash / ksh / zsh)で実行してください:
$ shopt -s globstar # set -o globstar in ksh
$ for f in **/*.gz ; do zcat "$f" |
awk '/A/ {s=1} s {d = d $0 ORS} /B=0/ {s=0; d=""}
/B=1/ {s=0; printf "%s", d; d=""} ' ; done
A
合計線ではなく中間線のみを印刷するには、B=1
合計ブロックの位置を置き換えます。/A/ {...}
/B=.../ {...}