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

awk:从文件中获取有关输入和输出文件名的信息,awk,Awk,我有一个名为“names.txt”的文件,其中包含字符串列表: apple banana orange 我有一个包含文件名的目录,其中包含“names.txt”中列出的字符串: 我想对目录中包含“names.txt”中字符串并以“\u file.txt”结尾的所有文件执行一个awk命令,并将新的outputfile保存为包含相同字符串并以“\u better\u file.txt”结尾的文件,因此这三个awk命令的基本功能是: awk '{print $1,$3}' apple_file.tx

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

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

我想对目录中包含“names.txt”中字符串并以“\u file.txt”结尾的所有文件执行一个awk命令,并将新的outputfile保存为包含相同字符串并以“\u better\u 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命令更有效地执行此操作的任何想法?

您可以在文件上循环,将
awk
命令应用于每个文件

在$(cat names.txt)中为f使用
;执行awk'{print$1,$3}'${f}_file.txt>${f}_better_file.txt;完成
,它给出:

# 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?在这种情况下,循环解决方案将不符合要求。

您可以在文件上循环以对每个文件应用
awk
命令

在$(cat names.txt)中为f使用
;执行awk'{print$1,$3}'${f}_file.txt>${f}_better_file.txt;完成
,它给出:

# 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?在这种情况下,循环解决方案将不符合要求。

尝试一下这一行,awk一行,单进程,无循环

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

希望它能给你想要的。

试试这一行,awk一行,单进程,无循环

awk 'NR==FNR{a[$0"_file.txt"]=$0"_better_file.txt";next}
    a[FILENAME]{print $1,$3 >> a[FILENAME] }' names.txt *_file.txt
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
希望它能给你想要的

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
上面读取NR==FNR块中的“names.txt”,并且对于names.txt中的每一行“foo”,它会在脚本将操作的文件名数组的末尾添加一个条目“foo_file.txt”(ARGV[])

NR==FNR块之后的部分是操作每个“foo_file.txt”文件的地方,步骤1是关闭以前打开的任何输出文件(如果有),以避免在某些AWK中出现“打开的文件太多”错误,然后通过添加“\u better”创建新的输出文件名在当前输入文件名的中间,给定一个输入文件名为“FooxField.txt”,它创建一个输出文件名为“FooxBeTythField.txt”。

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

上面读取NR==FNR块中的“names.txt”,并且对于names.txt中的每一行“foo”,它会在脚本将操作的文件名数组的末尾添加一个条目“foo_file.txt”(ARGV[])

NR==FNR块之后的部分是操作每个“foo_file.txt”文件的地方,步骤1是关闭以前打开的任何输出文件(如果有),以避免在某些AWK中出现“打开的文件太多”错误,然后通过添加“\u better”创建新的输出文件名在当前输入文件名的中间,给定一个输入文件名为“FooxField.txt”,它创建一个输出文件名为“FooxBeTythField.txt”。


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

假设任意数量的文件包含names.txt中的字符串,并以“\u file.txt”结尾(可能不必加前缀
apple
orange
等):


假设任意数量的文件包含names.txt中的字符串,并以“\u file.txt结尾(可能不必以
苹果
橙色
等作为前缀):


你的意思是更少的进程或更少的代码?我的意思是使用一个命令来使用输入文件“names.txt”,这在我的示例解决方案中没有使用。这里有数百个文件,而不仅仅是我举的三个作为例子。为什么你需要names.txt而不仅仅是对*\u file.txt进行操作?是否有一些*_file.txt文件是您不想操作的,因此names.txt是一个子集?实际上,您指的是更少的进程或更少的代码?我的意思是使用单个命令,使用输入文件“names.txt”,这在我的示例解决方案中现在没有使用。这里有数百个文件,而不仅仅是我举的三个作为例子。为什么你需要names.txt而不仅仅是对*\u file.txt进行操作?是否有一些*_file.txt文件是您不想操作的,因此names.txt是一个子集?您应该在测试中真正使用
文件名,而不是
文件名]
,以防文件名以
0…
开头。ITYM
顺便说一句,不是
>
-awk不是shell。在测试中,你应该在
中使用
文件名,而不是
一个[FILENAME]
,以防文件名以
0…
开头。ITYM
顺便说一句,而不是
>
-awk不是shell。
表示f的$(cat names.txt);执行awk'{print$1,$3}'${f}_file.txt>${f}_better_file.txt;done
有多个基本的shell编程错误(UUOC,无引号的变量,用于f in$(命令输出))。真正编写该循环的方法是
,而IFS=read-rf;执行awk“{print$1,$3}”${f}\u file.txt”>“${f}\u better\u file.txt”;完成
,但与仅使用1个awk命令相比,它仍然非常慢(请参见).wrt
用于f in$(ls-1*\u better\u file.txt)
-考虑一下与f in*\u better\u file.txt的
相比,这做了些什么。特别是阅读。我会阅读你的文档,谢谢你的链接。这是一个循环文件解决方案的POC,而不是复制粘贴到prod命令。这是为我做的,非常感谢<代码>表示f,单位为$(cat names.txt);执行awk'{print$1,$3}'${f}_file.txt>${f}_better_file.txt;done
有多个基本的shell编程错误(UUOC,无引号的变量,用于f in$(命令输出))。真正编写该循环的方法是
,而IFS=read-rf;执行awk“{print$1,$3}”${f}\u file.txt”>“${f}\u better\u file.txt”;完成了
,但与仅使用1个awk命令相比,它仍然非常慢(请参见).wrt
,对于$(ls-1*\u better\u file.txt)中的f来说
-想想这是什么