好的,所以花了两天后,我无法解决它,现在我几乎没时间了.这可能是一个非常愚蠢的问题,所以请耐心等待.我的awk脚本做了这样的事情:
BEGIN{ n=50; i=n; }
FNR==NR {
# Read file-1, which has just 1 column
ids[$1]=int(i++/n);
next
}
{
# Read file-2 which has 4 columns
# Do something
next
}
END {...}
Run Code Online (Sandbox Code Playgroud)
它工作正常.但现在我想将它扩展为3个文件.比方说,我不需要硬编码"n"的值,而是需要读取属性文件并从中设置值"n".我发现了这个问题,尝试过这样的事情:
BEGIN{ n=0; i=0; }
FNR==NR {
# Block A
# Try to read file-0
next
}
{
# Block B
# Read file-1, which has just 1 column
next
}
{
# Block C
# Read file-2 which has 4 columns
# Do something
next
}
END {...}
Run Code Online (Sandbox Code Playgroud)
但它没有用.块A是为file-0执行的,我能够从属性文件中读取属性.但是对于文件-1和文件-2都执行块B. 并且块C永远不会被执行.
有人可以帮我解决这个问题吗?我之前从未使用过awk,语法非常混乱.此外,如果有人可以解释awk如何从不同的文件中读取输入,那将非常有帮助.
如果我需要在问题中添加更多详细信息,请与我们联系.
如果你有gawk,只需测试ARGIND:
awk '
ARGIND == 1 { do file 1 stuff; next }
ARGIND == 2 { do file 2 stuff; next }
' file1 file2
Run Code Online (Sandbox Code Playgroud)
如果你没有傻瓜,那就去吧.
在其他awks中,您可以只测试文件名:
awk '
FILENAME == ARGV[1] { do file 1 stuff; next }
FILENAME == ARGV[2] { do file 2 stuff; next }
' file1 file2
Run Code Online (Sandbox Code Playgroud)
只有在你想要解析同一个文件两次时才会失败,如果是这种情况你需要添加文件被打开次数的计数.
更新:下面的解决方案有效,只要所有输入文件都是非空的,但请参阅@Ed Morton的答案,以获得更简单,更健壮的添加文件特定处理的方法.
但是,这个答案仍然提供了一些awk基本的有用解释,以及为什么OP的方法不起作用.
尝试以下(注意我已经将索引设置为1,因为它是如何awk做的):
awk '
# Increment the current-file index, if a new file is being processed.
FNR == 1 { ++fIndex }
# Process current line if from 1st file.
fIndex == 1 {
print "file 1: " FILENAME
next
}
# Process current line if from 2nd file.
fIndex == 2 {
print "file 2: " FILENAME
next
}
# Process current line (from all remaining files).
{
print "file " fIndex ": " FILENAME
}
' file-1 file-2 file-3
Run Code Online (Sandbox Code Playgroud)
FNR==1每当开始处理新的输入文件时,模式都为真(FNR包含输入文件相对行号).每次新文件开始处理时,fIndex都会递增,从而反映当前输入文件的从1开始的索引.对@ twalberg的帮助回答提示.
awk数字上下文中使用的未初始化变量默认为0,因此无需初始化fIndex(除非您需要不同的起始值).fIndex == 1然后可以使用诸如的模式来执行仅来自特定输入文件的行的块(假设块结束next).至于为什么你的方法不起作用:
对于来自所有输入文件的行,您的第2和第3个块可能无条件地执行,因为它们之前没有模式(条件).
因此,为所有后续输入文件中的行输入第二个块,然后其next语句将阻止第3个块到达.
潜在的误解:
也许您认为每个块都可以作为处理单个输入文件的循环.这不是多么awk有效.相反,整个awk程序在循环中处理,每次迭代处理单个输入行,从文件1的所有行开始,然后从文件2开始,......
一个awk程序可以有任意数量的块(通常以模式开头),并且它们是否为当前输入行执行仅受模式评估为真的控制; 如果没有模式,则无条件地执行该块(跨输入文件).但是,正如您已经发现的那样,next可以使用块内部跳过后续块(模式块对).