如何在awk中检测EOF?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在awk中检测EOF?相关的知识,希望对你有一定的参考价值。
有没有办法确定当前行是否是输入流的最后一行?
你有两个选择,两种都很混乱。
- 将每个当前行的副本存储在临时变量中,然后使用END块处理它。
- 使用system命令在BEGIN块中运行“wc -l | getline”以获取文件中的行数,然后计算该值。
您可能需要稍微使用#2来运行它,但它应该可以工作。自从我做了任何awk以来已经有一段时间了。
你可以试试这个:
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。
特殊的END
模式将仅在所有输入结束后匹配。请注意,此模式不能与任何其他模式组合使用。
更有用的可能是getline
伪函数,它将$0
重置为下一行并返回1,或者在EOF返回0的情况下!我认为这就是你想要的。
例如:
awk '{ if(getline == 0) { print "Found EOF"} }'
如果您只处理一个文件,这将是等效的:
awk 'END { print "Found EOF" }'
这些是按照从最好到最差的顺序做你想做的事情的唯一明智的方法:
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块中进行EOF处理,在END块中进行。
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块。
I'm not even sure how to categorize this "solution"
{
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
}
关于这个黑客的一件很酷的事情是,通过分配给$0
,所有剩余的声明性模式和动作都有效,一行延迟了。你不能让它们为END
工作,即使你把END
放在最上面,但是你确实控制了最后一行而你还没有做任何其他事情。
gawk实现有一个名为ENDFILE
的特殊规则,它将在处理参数列表中的每个文件后触发。这有效:
awk '{line=$0} ENDFILE {print line}' files...
你可以找到更多细节here>>
一种简单的方法是通过中间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.'
要检测参数列表中每个文件的最后一行,以下方法很有效:
FNR == 1 || EOF {
print "last line (" FILENAME "): " $0
}
嗯,当你已经到达END
时,awk EOF
变量告诉你。我猜对你来说真的没什么帮助
以上是关于如何在awk中检测EOF?的主要内容,如果未能解决你的问题,请参考以下文章
在一个片段中检测Recyclerview的上下滑动,我怎么做?