
grep
現在のテキスト文字列を検索し、awk
必要な変数をフィルタリングするために使用するデータを含むいくつかのtxtファイルがあります。文字列がファイル内で繰り返されるので、現在このコマンドを使用して目的の文字列を抽出しています。
grep 'text' *.txt | awk ' NR==1 {print $2 } ' > outputfile
問題は、フォルダ内の複数のファイルを繰り返し、抽出された変数を各ファイルの単一の出力ファイルに書きたいということです。この質問に対する回答は以前にすでに回答されていることがわかっていますが、これは初めてであり、実装するのが困難です。
どんなフィードバックでも大変感謝します!
答え1
各反復の出力を別の出力ファイルにリダイレクトできるように、各ファイルのファイル名を保持しながらbash内のファイルを繰り返します。
たとえば、次のようになります(テストされていません)。
PREFIX="/tmp/outputs" # define where to store all the outputs
mkdir -p "${PREFIX}" # make sure the outputs dir exists
for FILE in *.txt # get the file names you want to work on
do
# use ${PREFIX}/${FILE} to redirect output to a
# file that's associated with the input
grep 'text' "${FILE}" | awk ' NR==1 {print $2 } ' > "${PREFIX}/${FILE}"
done
答え2
.txt
私が正しく理解したら、各ファイルに対して次のことを行う必要があります。
- パターンを含む最初の行を見つけます
text
。 - この行では、スペースで区切られた2番目のフィールドを入力ファイルに関連付けられている名前のファイルに書き込みます。
出力ファイル名の設定方法は説明していません。入力ファイルと同じに.out
しますが.txt
。
シェルループを使用してこれを行うことができます。
for x in *.txt; do
grep 'text' -- "$x" | awk '{print $2; exit}' >"${x%.*}.out"
done
読み続けるように指示し、何もしないよりも、作業が完了した直後にawkを終了する方が高速です。もう1つの可能性は、awkを完全にスキップし、シェルに行分割を実行させることです(これがより速いか遅いかは、多くの要因によって異なり、予測に危険を与えません)。
for x in *.txt; do
grep 'text' -- "$x" | read -r first second rest && printf '%s\n' "$rest" >"${x%.*}.out"
done
別のアプローチは、すべてのタスクをawkで実行することです。 awkは複数のファイルで動作でき、awkの出力リダイレクトを使用できます。これには少ないプロセスが必要です。 Gawk(GNU awk)では非常に簡単です。
awk '/text/ {print $2 >substr(FILENAME, 1, length(FILENAME)-4) ".out"; nextfile}' *.txt
awk実装がない場合は、nextfile
次のファイルへの変換を手動で処理する必要があるため、このアプローチはあまり魅力的ではありません(より複雑で効率的ではありません)。
awk '
FNR==1 {first=1}
first && /text/ {print $2 >substr(FILENAME, 1, length(FILENAME)-4) ".out"; first=0}' *.txt