我有这种奇怪的现象,我不明白。我想我在awk中缺少一些重要的东西。当有一行包含SIGNAL时,我希望将整行连接到一个名为'c'的字符串。该字符串以“a”和“b”的串联开头,工作正常。
档案in.dat
:
SIGNAL Hello1!
档案tt.awk
:
BEGIN { a = "a"; b = "b"; c = a b; }
/SIGNAL/ { c = c " " $0; }
END { print c; }
当我awk -f tt.awk in.dat
时,我得到(正如预期的那样):
ab SIGNAL Hello1!
现在我将in.dat
更改为:
SIGNAL Hello1!
SIGNAL Hello2!
然后我再次awk -f tt.awk in.dat
得到:
SIGNAL Hello2!1!
我希望看到:
ab SIGNAL Hello1! SIGNAL Hello2!
我在我的CentOS shell上进行此操作(我的~/.cshrc
文件中有大量设置)。我在我的Cygwin shell上检查了这些,它按照我的预期正常工作。我的CentOS shell设置有问题。它可能是什么?
答案 0 :(得分:2)
这是DOS行结尾的问题(如上面的评论中的Etan Reisner所述)。您的第二版in.dat
使用\r\n
进行换行,awk
无法处理。{/ p>
使用相同的tt.awk
代码:
$ echo "SIGNAL Hello1\!\nSIGNAL Hello2\!" |awk -f tt.awk
ab SIGNAL Hello1! SIGNAL Hello2!
$ echo "SIGNAL Hello1\!\r\nSIGNAL Hello2\!" |awk -f tt.awk
SIGNAL Hello2!1!
想知道这是做什么的?在UNIX中,\r
将位置重置到最左边的位置,但不向下发送一行(这就是\n
所做的)。 DOS将\n
解释为一行而不是重置到最左边的位置,而UNIX将\r
隐含为隐式。
以下是一些实验来说明正在发生的事情:
$ echo "SIGNAL Hello1\!\r\nSIGNAL Hello2\!"
SIGNAL Hello1!
SIGNAL Hello2!
$ echo "SIGNAL Hello1\!\rSIGNAL Hello2\!"
SIGNAL Hello2!
$ echo "ab SIGNAL Hello1\!\n SIGNAL Hello2\!"
ab SIGNAL Hello1!
SIGNAL Hello2!
$ echo "ab SIGNAL Hello1\!\r SIGNAL Hello2\!"
SIGNAL Hello2!1!
特别注意最后两项。 awk
为您剥离\n
,但保留\r
,因此第一行打印为ab SIGNAL Hello1!
,然后应用\r
,第二行 signal Hello2!
在第一行的之上写着。第一行的最后两个字符(1!
)仍然存在,因为第二行不足以覆盖它们。
现在我们知道了这个问题,我们可以修复代码:
BEGIN { a = "a"; b = "b"; c = a b; }
/SIGNAL/ { gsub(/\r/, ""); c = c " " $0; }
END { print c; }
这会从添加到\r
的行中删除所有c
。