如何对不同的文件应用相同的 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

或者在一行中:

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

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

答案2

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

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

不算漂亮,只是速度快了一点。

说明按照评论中的要求。

FNRF伊莱n数字或record) 类似于NR(n数字或record),但 whileNR是所有输入记录的连续序列号,FNR在开始处理新输入文件时重置为 1。

4.0 的唯一替代gawk方案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

答案3

老问题,但考虑到我上次看到单核个人计算机是十年前,你可以使用 gnu parallel

解决shell的引号扩展和解释

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

使用正确的 glob 来选择输入文件。在这里,我用来{.} 从输出名称中取出扩展名,因为我会在之后附加它

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

其中X是您想要使用的处理器数量,您仍然可以使用 1。这将为您提供file[1-9]_sorted.tex输出

相关内容