同じawkアクションを異なるファイルに適用する方法は?


8

私はawkの初心者で、これを行うawkスクリプトを作成できるかどうかはわかりません。

何百ものデータファイルを並べ替える必要があります。それぞれについて、次のワンライナーを使用します。

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

必要な出力が得られます。ただし、このアクションを自動化して、各ファイルを取得し、アクションを適用して、対応するソート済みファイルを書き込むスクリプトを作成したいと思います。

よろしくお願いします!

回答:


7

awkコードを変更する場合、単一のawkプロセスで解決でき、シェルループはありません。

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

美しさではなく、わずかに速くなります。

コメントで要求された説明

FNRf ile n umberまたはr ecord)はNRn umberまたはr ecord)に似ていNRますが、FNRはすべての入力レコードの連続シーケンス番号ですが、新しい入力ファイルの処理が開始されると1にリセットされます。

gawk4.0のみの代替FNR==1BEGINFILE特別なパターンです。

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

@manatworkに感謝!それは素晴らしかった。前の回答とは異なり、このワンライナーがどのように機能するかは正確にはわかりませんが、実際には機能しました。お時間がありましたら、何ができるか説明していただければ幸いFNR==1です。=)
Nacu

12

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}


1
その「シェル固有の構文」はPOSIXにあり、保証期間中のほとんどすべてのUNIXシステムで利用可能であり、多くはそうではありません。
Gilles「SO-悪をやめる」

@Arcegeに感謝!シェルとしてemacsを使用します。あなたの提案はかなり理解できますが、私はそれを使う方法がわかりません。私が理解し、慣れている限り、適用するファイルまたはフォルダーの前に実行する.awkスクリプトを記述します。私は正しいですか?私はそうしましたが、これは私が使用方法を知らない別の種類のスクリプトのようです。
Nacu

emacs(<kbd> Mx </ kbd> shell)内でシェルを実行し、その内部でプロンプトで上記のコマンドを実行できます。またはターミナルを開き、そこでコマンドを実行します。スクリプトを指定するには2つの方法があります(awk、シェルなど)。コマンドラインまたはファイルのいずれかです。あなたのawk投稿でのコマンドは、コマンドライン形式を使用しています。私の "1行"コマンドもコマンドラインフォームです。
Arcege、2012

0

古い質問ですが、シングルコアのパーソナルコンピュータを最後に見たのは10年前だったので、GNUパラレルを使用できます。

シェルの展開と引用の解釈を解決するには

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

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

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

ここXで、使用するプロセッサの数は1でも使用できます。これによりfile[1-9]_sorted.tex、出力として得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.