同じawk操作を別のファイルに適用するには?

同じawk操作を別のファイルに適用するには?

私は最初にawkに触れましたが、これを行うためにawkスクリプトを書くことができるかどうかわかりません。

ソートする必要があるデータファイルは何百ものあります。それぞれに次の行を使用します。

awk 'ORS=NR%3?" ":"\n" ' file1.tex >  file1_sorted.tex
awk 'ORS=NR%3?" ":"\n" ' file2.tex >  file2_sorted.tex
...

必要な結果を得る。しかし、私はこのタスクを自動的に実行し、各ファイルをインポートし、タスクを適用し、対応するソートされたファイルを作成するスクリプトを持ちたいと思います。

ご協力ありがとうございます!

答え1

forループに次のファイルを適用できます。

for file in *.tex;
do
    awk 'ORS=NR%3?" ":"\n"' "$file" > "$(basename "$file")_sorted.tex"
done

または1行で:

for file in *.tex; do awk 'ORS=NR%3?" ":"\n"' $file > "$(basename "$file" .tex)_sorted.tex"; done

どのシェルも指定していないので、シェル固有の構文をbasename使用するのではなく、より標準的なシェルを使用してください${file%%.tex}

答え2

awkコードを変更すると、awkシェルループなしで単一プロセスで問題を解決できます。

awk 'FNR==1{if(o)close(o);o=FILENAME;sub(/\.tex/,"_sorted.tex",o)}{ORS=FNR%3?" ":"\n";print>o}' *.tex

きれいではありません。少し早くなっただけです。

説明するコメントでリクエストしたとおり。

FNRFエリーN数字またはアル字型エコ)はNRN数字またはアル字型ecord)、ただし、NRすべての入力レコードのシーケンシャルシーケンス番号ですが、FNR新しい入力ファイルの処理が開始されると1にリセットされます。

4.0の唯一のgawk選択肢は特殊モードFNR==1です。BEGINFILE

awk '
FNR==1{   # first record of an input file?
  if(o)close(o);   # was previous output file? close it
  o=FILENAME;sub(/\.tex/,"_sorted.tex",o)   # new output file name
}
{
  ORS=FNR%3?" ":"\n";   # set ORS based on FNR (not NR as in the original code)
  print>o   # print to the current output file
}
' *.tex

答え3

古い質問です。私がシングルコアPCを最後に見たのが10年前であることを考えると、GNUパラレルを使うことができます。

シェル引用符の拡張と解釈の解決

my_awk='ORS=NR%3?" ":"\n"' 

正しいグローブを使用して入力ファイルを選択してください。ここでは{.} 後で追加するので、出力名から拡張子を削除するために使用します。

parallel -jX "awk '$my_awk' {} > {.}_sorted.tex" ::: *.tex

X使用するプロセッサの数はどこにありますか?それでも1を使用できます。これはあなたにfile[1-9]_sorted.tex出力を与えるでしょう

関連情報