好的,所以花了2天后,我无法解决它,现在我几乎没时间了。这可能是一个非常愚蠢的问题,所以请耐心等待。我的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 {...}
工作正常。但现在我想将它扩展为3个文件。让我们说,不是硬编码" n"的值,我需要读取属性文件并设置" n"的值。从那以后。我找到了this question,并尝试过这样的事情:
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 {...}
但它不起作用。块A是为file-0执行的,我能够从属性文件中读取属性。但是对于文件-1和文件-2都执行块B.并且块C永远不会被执行。
有人可以帮我解决这个问题吗?我之前从未使用过awk,语法非常混乱。此外,如果有人可以解释awk如何从不同的文件中读取输入,那将非常有用。
如果我需要在问题中添加更多详细信息,请与我们联系。
答案 0 :(得分:8)
如果你有傻瓜,只需测试ARGIND:
awk '
ARGIND == 1 { do file 1 stuff; next }
ARGIND == 2 { do file 2 stuff; next }
' file1 file2
如果你没有傻瓜,那就去吧。
在其他问题中,您可以只测试文件名:
awk '
FILENAME == ARGV[1] { do file 1 stuff; next }
FILENAME == ARGV[2] { do file 2 stuff; next }
' file1 file2
只有在你想要解析同一个文件两次时才会失败,如果是这种情况你需要添加文件被打开次数的计数。
答案 1 :(得分:6)
更新:只要所有输入文件都是非空 ,下面的解决方案就可以正常工作,但会看到@Ed Morton's answer为了更简单,更健壮的方式添加特定于文件的处理。
然而,这个答案仍然提供了一些希望有用的解释,说明了一些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
FNR==1
包含输入文件相对行号),模式FNR
就为真。每次新文件开始处理时,fIndex
都会递增,从而反映当前输入文件的从1开始的索引。 提示@twalberg's helpful answer。
awk
变量默认为0
,因此无需初始化fIndex
(除非您需要不同的起始值)。fIndex == 1
之类的模式来执行仅来自特定输入文件的行的块(假设块以next
结尾)。至于为什么你的方法不起作用:
对于来自所有输入文件的行,您的第2和第3个块可能无条件执行 ,因为它们之前没有模式(条件)。
因此,为所有后续输入文件中的行输入了第2个块,而其next
语句则阻止第3个块到达
潜在的误解:
也许您认为每个块都可以作为处理单个输入文件的循环。这不是awk
的工作原理。相反,整个awk
程序在循环中处理,每次迭代处理单个输入行,从文件1的所有行开始,然后从文件开始2,......
awk
程序可以包含任意数量的块(通常以模式开头),并且它们是否为当前输入行执行仅受模式评估为真的控制;如果没有模式,则无条件地执行 (跨输入文件)。但是,正如您已经发现的那样,块中的next
可用于跳过后续块(模式块对)。
答案 2 :(得分:1)
也许您需要考虑添加一些额外的结构:
BEGIN { file_number=1 }
FNR==1 { ++file_number }
file_number==3 && /something_else/ { ...}