awk的记录范围:该行的最后一个字段被忽略?

时间:2014-10-20 08:42:32

标签: awk

如果我有一个文件:

0
on
0
off
0
0
...

命令:

awk '$1 == "on", $1 == "off"' < file

什么都不返回。 奇怪的是,如果我将输入文件更改为:

0
on ;
0
off ;
0
0

返回的值如预期:

on ;
0
off ;

这里发生了什么?如果我的字段是最后一行,似乎awk不喜欢它。 我尝试更改$1的{​​{1}}和$0的{​​{1}},但没有取得更多成功。

有没有办法处理作为记录最后一个字段的awk记录范围?

参考:This page of the awk manual

3 个答案:

答案 0 :(得分:1)

执行此操作时:

awk '...' < file

您正通过标准输入流将文件传递给awk。这与做

不同
awk '...' file

将文件名传递给awk以便打开。通常,这两种方法是等价的。但是,由于行结尾的不同,Windows上出现了问题。

此示例演示了此问题:

$ awk '{for(i=1; i<=NF; ++i)print NR, i, "|"$i"|"}'  < file.txt
| 1 |0
| 1 |on
| 1 |0
| 1 |off
| 1 |0
6 1 |0|

将输出与此比较:

$ awk '{for(i=1; i<=NF; ++i)print NR, i, "|"$i"|"}' file.txt
1 1 |0|
2 1 |on|
3 1 |0|
4 1 |off|
5 1 |0|
6 1 |0|

第二次测试的输出是预期的输出。问题是回车\r在第一种情况下被解释为记录的一部分。

在GNU awk上,可以指定一个多字符记录分隔符,它允许您通过标准输入传递文件的内容:

$ awk '{for(i=1; i<=NF; ++i)print NR, i, "|"$i"|"}' RS='\r\n' < file.txt
1 1 |0|
2 1 |on|
3 1 |0|
4 1 |off|
5 1 |0|
6 1 |0|

答案 1 :(得分:1)

输入文件中有control-Ms,在运行命令之前使用dos2unix或类似命令将其删除。

此外 - 使用范围表达式永远不会有用,因为它们使得微不足道的事情稍微简单但是任何事情甚至更加复杂(例如,不打印开始和/或结束行)会导致您编写重复的代码或完成重复操作-写。只需使用标志:

awk '$1 == "on"{f=1} f; $1 == "off"{f=0}' file

答案 2 :(得分:0)

你可以尝试下面的awk命令,

$ awk '$1 == "on", $1 == "off"' file
on
0
off

awk -v RS="[\n\r]+" '$1 == "on", $1 == "off"' file

输入文件中可能存在回车\r的可能性。因此,将记录分隔符设置为[\n\r]+。此正则表达式将一个或多个换行符或回车符作为值分配给记录分隔符变量。