加入以反斜杠结尾的行,下一行是awk(来自Famous awk one-liners解释)

Son*_*ein 2 bash awk sed

这项练习来自AWK单行人员Peteris Krumins解释的博客文章

基本上就是这一行

 awk '/\\$/ { sub(/\\$/,""); getline t; print $0 t; next }; 1'
Run Code Online (Sandbox Code Playgroud)

用下一行连接以反斜杠结尾的每一行:

例如输入

12345\
6789
523435\
00000
Run Code Online (Sandbox Code Playgroud)

产量

123456789
52343500000
Run Code Online (Sandbox Code Playgroud)

博客文章说:不幸的是,这一个班轮无法加入超过2行(这是留给读者的练习,以提出一个连接任意数量的行以反斜杠结束的单行:)).

所以使用上面的AWK单行,如果你使用一个接一个的输入文件,一个接一个地在结尾有一个反斜杠(input2),给出一个错误的答案(output2),例如input2

12345\
6789\
523435\
00000
Run Code Online (Sandbox Code Playgroud)

输出2 - 不正确

123456789\
52343500000
Run Code Online (Sandbox Code Playgroud)

我认为,根据帖子,输出应该输出3:

输出3 - 正确

12345678952343500000
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题(输入为input2并获取output3)?

mkl*_*nt0 5

请尝试以下方法:

awk '/\\$/ { printf "%s", substr($0, 1, length($0)-1); next } 1' <<'EOF'
12345\
6789\
523435\
00000
EOF
Run Code Online (Sandbox Code Playgroud)

产量

12345678952343500000
Run Code Online (Sandbox Code Playgroud)

这表明3个连续(或更多)行继续工作正常,与问题中的命令不同.

命令说明:

  • /\\$/匹配一条线\的末尾($),信号线延续.
  • substr($0, 1, length($0)-1)\从输入行中删除该尾随$0.
  • 通过使用printf "%s",(修改的)当前行被打印而没有尾随换行符,这意味着接下来的任何打印命令将直接附加到它,有效地加入当前行和下一行.
  • next 完成当前行的处理.
  • 1是一种常用的awk简写{ print },即简单地打印输入行(带尾随\n).

至于为什么原始命令不起作用:

awk '/\\$/ { sub(/\\$/,""); getline t; print $0 t; next }; 1
Run Code Online (Sandbox Code Playgroud)
  • 遇到行继续符(\在当前行的末尾)时,从文件中getline t读取下一行并按原样当前行之后打印.
  • next然后完成当前和 - 由于getline调用 - 下一行的处理,以便下一个脚本循环处理下一之后的行(当前行的2行).
  • 因此,由于线读取通过getline被盲目打印而不以任何方式检查,因此相对于行继续字符处理跳过它.

一般来说,正如Ed Morton在评论中指出的那样,使用getline很少是正确的解决方案并且可能导致微妙的错误 - 请参阅http://awk.info/?tip/getline.

  • awk数组和字符串从索引1开始,而不是0.`substr($ 0,0,...)`只是做你想要的,因为`substr()`找到一个无效的索引,如'0`作为第二个arg它默认为"1".使用`substr($ 0,1,...)`. (3认同)