修正する

修正する

特定のcsvファイルを名前でフィルタリングしてから、2行目を単一のcsvファイルに抽出する方法を見つけようとしています。ファイルを見つけて、sed / awkなどのコマンドを使用してパイプして必要な行を抽出するのが良いアイデアかどうかわかりません。

find -name "data.csv" | sed -n 2p > final.csv 

修正する

Bashスクリプトでforループを使用すると、目的の出力が生成されますが、すべての出力が1行に印刷されます。

for OUTPUT in $(find -name "data.csv")
do

        sed -n 2p $OUTPUT

done

あなたの提案を助けてください。

答え1

出力を見ると、find -name "data.csv"というファイルのフルパス名が印刷されていることがわかりますdata.csv。これをにパイプすると、sed入力の2行目が印刷されます。

したがって、あなたが言うのは、「これはファイルのリストです。リストの2番目のファイルを教えてください」と言いたいのは、「これはファイルのリストです。ファイルごとに2行目を教えてください」です。 「このために使用したいですxargs

おそらくあなたは

find -name "data.csv" -print0 | xargs -0 -n 1 sed -n 2p > final.csv

:を使用して、ファイル名間の区切り文字として改行の代わりにNUL文字を使用し、それを期待するように指示することをお勧めしfind -print0 | xargs -0ます。これにより、スペース、キャリッジリターン、またはその他の奇妙な文字を含むファイル名がパイプラインを複雑にするのを防ぎます。-print0find-0xargs

バッチ処理を試みるのではなく、見つかっ-n 1た各「data.csv」ファイルに対してxargs別々のプロセスを実行するように指示するため、通常は操作がより効率的です。sedこの場合、実行すると

sed -n 2p file1 file2 file3

内部的には、すべての入力ファイルを単一の入力ストリームにリンクし、その入力ストリームの2行目を印刷します。しかし、RTFM:おそらくこれをしない方法がありますsed。しかし、私はそれを逃しています。

答え2

検索結果は、sed が操作を実行するために必要なファイル名のリストです。そのため、xargsを使用してそのリストから1つずつsedを実行します。ただし、ファイル名にはスペースと改行文字を含めることができるため、ファイル名をASCII 0で区切るfindの "-print0"オプションを使用することをお勧めします。また、これらのファイルが大きい場合は、2行目以降に停止してCPU列を節約できます。これにより、次のようになります。

find -name "data.csv" -print0 | xargs -0 -n 1 sed -n -e 2p -e 2q > final.csv

答え3

次のことができます。

find -name "data.csv" | xargs -n 1 sed -n 2p >> final.csv

上記の方法は、>>sedの結果を新しい行からFinal.csvにリンクするのではなく、>Final.csvの内容をsedの出力に置き換えることです。

関連情報