如何将相同的 awk 操作应用于不同的文件?

Nac*_*acu 8 shell awk

我是 awk 的新手,我不知道是否可以编写一个执行此操作的 awk 脚本:

我有数百个数据文件需要排序。对于每一个,我使用以下单行:

awk 'ORS=NR%3?" ":"\n" ' file1.tex >  file1_sorted.tex
awk 'ORS=NR%3?" ":"\n" ' file2.tex >  file2_sorted.tex
...
Run Code Online (Sandbox Code Playgroud)

我得到了我需要的输出。但是,我想要一个脚本来自动执行此操作,获取每个文件,应用该操作并编写相应的排序文件。

我将不胜感激您的帮助!

Arc*_*ege 12

您可以在 for 循环中应用文件:

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

或者在一行上:

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

由于您没有指定哪个 shell,请使用更标准的 shell,basename而不是使用特定于 shell 的语法${file%%.tex}


man*_*ork 7

如果修改awk代码,可以通过单awk进程和无shell循环解决:

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

不是美,只是速度略快。

评论中要求的解释

FNR˚F ILE ñ棕土或- [R的eCord)类似于NRñ棕土或- [R的eCord),但同时NR是所有输入记录的连续的序列号,FNR被复位为1,开始一个新的输入文件的处理时。

gawk对4.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
Run Code Online (Sandbox Code Playgroud)