【发布时间】:2009-10-29 21:22:42
【问题描述】:
有没有办法判断当前行是否是输入流的最后一行?
【问题讨论】:
有没有办法判断当前行是否是输入流的最后一行?
【问题讨论】:
特殊的END 模式只会在所有输入结束后匹配。请注意,此模式不能与任何其他模式结合使用。
更有用的可能是getline 伪函数,它将$0 重置到下一行并返回1,或者在EOF 的情况下返回0!我认为这是您想要的。
例如:
awk '{ if(getline == 0) { print "Found EOF"} }'
如果您只处理一个文件,这将是等效的:
awk 'END { print "Found EOF" }'
【讨论】:
cmd="cat file2"; while(condition) {if(cmd | getline line2 == 0) break;
你有两个选择,都有些混乱。
您可能需要稍微玩一下#2 才能让它运行,但它应该可以工作。自从我做任何 awk 以来已经有一段时间了。
【讨论】:
RECORDS=$(cat myfile | wc -l); awk 'NR == '${RECORDS}' {print "Last Line"}' myfile。嘿,当您选择 AWK 时,您已经超越了优雅。 :)
这些是做你想做的事的唯一明智的方法,按从最好到最坏的顺序排列:
awk 'NR==FNR{max++; next} FNR == max { print "Final line:",$0 }' file file
awk -v max="$(wc -l < file)" 'FNR == max { print "Final line:",$0 }' file
awk 'BEGIN{ while ( (getline dummy < ARGV[1]) > 0) max++; close(ARGV[1])} FNR == max { print "Final line:",$0 }' file
【讨论】:
当命令行上有多个文件时,检测 EOF 不太可靠。检测文件的开头更可靠。
为此,第一个文件是特殊的,我们忽略 FNR==1。
在第一个文件之后,FNR==1 成为前一个文件的结尾。 last_filename 始终包含您正在处理的文件名。
在 else 之后进行文件处理。
在 else 块和 END 块中执行 EOF 处理。
gawk 'BEGIN{last_filename="";} \
FNR==1{if (last_filename==""){last_filename=FILENAME;} \
else {print "EOF: "last_filename;last_filename=FILENAME;}} \
END{print "END: "last_filename;}' $*
对于多个文件集,else 块在 EOF 处对除最后一个文件之外的所有文件执行。最后一个文件在 END 块中执行。
对于单个文件集,不执行 else 块,而是执行 END 块。
【讨论】:
{
t = lastline
lastline = $0
$0 = t
}
/test/ {
print "line <" $0 "> had a _test_"
}
END {
# now you have "lastline", it can't be processed with the above statements
# ...but you can work with it here
}
这个 hack 很酷的一点是,通过分配给 $0,所有剩余的声明性模式和操作都可以工作,延迟一行。即使您将END 放在顶部,您也无法让它们为END 工作,但是您确实可以控制最后一行并且您没有做任何其他事情它。
【讨论】:
检测参数列表中每个文件的最后一行 以下效果很好:
FNR == 1 || EOF {
print "last line (" FILENAME "): " $0
}
【讨论】:
一种简单的方法是通过中间的sed 脚本运行文件,该脚本在每个非最后一行放置一个 0,在最后一行放置一个 1。
cat input_file | sed 's/^/0/;$s/0/1/' | awk '{LST=/^1/;$0=substr($0,2)}
... your awk script in which you can use LST to check for the
... last line.'
【讨论】:
嗯,awk END 变量告诉您何时已经到达 EOF。我猜对你真的没有多大帮助
【讨论】:
你可以试试这个:
awk 'BEGIN{PFNR=1} FNR==PFNR{PFNR++;next} {print FILENAME,PFNR=2} END{print FILENAME}' file1 file2
【讨论】:
A portable solution is provided in the gawk user manual,虽然在另一个答案中提到,gawk 本身有 BEGINFILE 和 ENDFILE。
【讨论】: