awk字符串连接不起作用2(shell设置错误?)

时间:2016-03-31 00:56:01

标签: shell awk

我有这种奇怪的现象,我不明白。我想我在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设置有问题。它可能是什么?

1 个答案:

答案 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