awk:从文件中获取有关输入和输出文件名的信息

时间:2017-08-25 11:48:46

标签: awk

我有一个名为“names.txt”的文件,其中包含字符串列表:

apple
banana
orange

我有一个目录,其中包含的文件名包含“names.txt”中列出的字符串:

apple_file.txt
orange_file.txt
banana_file.txt

我想对目录中包含“names.txt”中的字符串并以“_file.txt”结尾的所有文件执行awk命令,并将新的outputfile保存为包含相同字符串并结束的文件使用“_better_file.txt”,基本上这三个awk命令的作用是什么:

awk '{print $1,$3}' apple_file.txt > apple_better_file.txt 
awk '{print $1,$3}' banana_file.txt > banana_better_file.txt 
awk '{print $1,$3}' orange_file.txt > orange_better_file.txt 

通过使用“names.txt”文件,有关如何比上述三个awk命令更有效地做到这一点的想法吗?

4 个答案:

答案 0 :(得分:1)

您可以遍历文件以将awk命令应用于每个文件。

使用for f in $(cat names.txt); do awk '{ print $1,$3 }' ${f}_file.txt > ${f}_better_file.txt; done,它会:

# cat names.txt
apple
banana
orange
# ls -1 *_file.txt
apple_file.txt
banana_file.txt
orange_file.txt
# for f in $(ls -1 *_file.txt); do echo $f; cat $f; done
apple_file.txt
foo bar foo
aze rty aze
foo bar foo
banana_file.txt
foo bar foo
aze rty aze
foo bar foo
orange_file.txt
foo bar foo
aze rty aze
foo bar foo
# for f in $(cat names.txt); do awk '{ print $1,$3 }' ${f}_file.txt > ${f}_better_file.txt; done
# for f in $(ls -1 *_better_file.txt); do echo $f; cat $f; done
apple_better_file.txt
foo foo
aze aze
foo foo
banana_better_file.txt
foo foo
aze aze
foo foo
orange_better_file.txt
foo foo
aze aze
foo foo
#

或许你想只使用awk?在这种情况下,循环解决方案不会遵守。

答案 1 :(得分:1)

试试这行,awk单行,单个进程,无循环。

awk 'NR==FNR{a[$0"_file.txt"]=$0"_better_file.txt";next}
    a[FILENAME]{print $1,$3 >> a[FILENAME] }' names.txt *_file.txt

希望它能满足您的需求。

答案 2 :(得分:1)

awk '
NR==FNR{ ARGV[ARGC]=$0"_file.txt"; ARGC++; next }
FNR==1 { close(out); out=FILENAME; sub(/_[^_]+$/,"_better&",out) }
{ print $1, $3 > out }
' names.txt

上面的内容是" names.txt"在NR == FNR块中,对于每一行" foo"在names.txt中,它添加了一个条目" foo_file.txt"到脚本将在其上运行的文件名数组的末尾(ARGV [])。

NR == FNR块之后的部分是每个" foo_file.txt"正在操作文件,步骤1是关闭任何以前打开的输出文件(如果有的话),以避免得到太多打开的文件"某些awks中出错,然后通过添加" _better"创建一个新的输出文件名在当前输入文件名的中间,因此输入文件名为" foo_file.txt"它创建了一个输出文件名" foo_better_file.txt"。

然后最后一行只是将您感兴趣的2个字段从输入文件打印到输出文件中。

答案 3 :(得分:1)

假设任意数量的文件包含来自 names.txt 的字符串,并以" _file.txt " (可能不必以apple_orange_等为前缀:

for f in $(grep -lf names.txt *_file.txt); do awk '{print $1,$3}' "$f" > "${f/_file/_better_file}"; done