将以反斜杠结尾的行与下一行 awk 连接起来(来自 Famous awk one-liners explained)
Join a line ending with a backslash with the next line awk (from Famous awk one-liners explained)
本练习来自AWK one-liners explained blog post by Peteris Krumins
基本上是这一行
awk '/\$/ { sub(/\$/,""); getline t; print [=10=] t; next }; 1'
将以反斜杠结尾的每一行与下一行连接起来:
例如输入
12345\
6789
523435\
00000
输出
123456789
52343500000
博客 post 说:
不幸的是,这个衬里无法连接超过 2 行(这留作 reader 的练习,以提出一个连接任意数量的以反斜杠结尾的行的衬里 :))。
因此,使用上面的 AWK 单行代码,如果您使用一个包含 2 行或更多行且末尾有反斜杠的输入文件 (input2),则会给出错误的答案 (output2)
例如输入2
12345\
6789\
523435\
00000
输出 2 - 不正确
123456789\
52343500000
我认为,根据 post,输出应该改为 output3:
输出 3 - 正确
12345678952343500000
如何解决这个问题(输入为 input2 并得到 output3)?
尝试以下操作:
awk '/\$/ { printf "%s", substr([=10=], 1, length([=10=])-1); next } 1' <<'EOF'
12345\
6789\
523435\
00000
EOF
产生
12345678952343500000
这表明 3 连续(或更多)行延续工作正常,与问题中的命令不同。
命令解释:
/\$/
匹配一行末尾 ($
) 的 \
,表示行继续。
substr([=16=], 1, length([=16=])-1)
从输入行 [=18=]
. 中删除尾随 \
- 通过使用
printf "%s"
,(修改后的)当前行打印时没有尾随换行符,这意味着接下来出现的任何打印命令都将直接附加到它后面,有效地将当前行和下一行连接起来。
next
完成当前行的处理。
1
是一个常见的 awk
习语,它是 shorthand for { print }
,即,用于简单地打印输入行(尾随 \n
).
至于为什么原来的命令不起作用:
awk '/\$/ { sub(/\$/,""); getline t; print [=12=] t; next }; 1
- 遇到行继续符(
\
在当前行的末尾),getline t
从文件中读取 next 行并在 current 行之后 按原样 打印它。
next
然后完成对当前和 - 由于 getline
调用 - next 行的处理,以便下一个脚本循环处理after 行 next 行(当前行的 2 行)。
- 因此,由于通过
getline
读取的行是盲目打印的并且未以任何方式检查,因此在行继续字符处理方面 跳过了 。
一般来说,正如 Ed Morton 在评论中指出的那样,使用 getline
很少是正确的解决方案,并且可能导致细微的错误 - 请参阅 http://awk.info/?tip/getline.
本练习来自AWK one-liners explained blog post by Peteris Krumins
基本上是这一行
awk '/\$/ { sub(/\$/,""); getline t; print [=10=] t; next }; 1'
将以反斜杠结尾的每一行与下一行连接起来:
例如输入
12345\
6789
523435\
00000
输出
123456789
52343500000
博客 post 说: 不幸的是,这个衬里无法连接超过 2 行(这留作 reader 的练习,以提出一个连接任意数量的以反斜杠结尾的行的衬里 :))。
因此,使用上面的 AWK 单行代码,如果您使用一个包含 2 行或更多行且末尾有反斜杠的输入文件 (input2),则会给出错误的答案 (output2) 例如输入2
12345\
6789\
523435\
00000
输出 2 - 不正确
123456789\
52343500000
我认为,根据 post,输出应该改为 output3:
输出 3 - 正确
12345678952343500000
如何解决这个问题(输入为 input2 并得到 output3)?
尝试以下操作:
awk '/\$/ { printf "%s", substr([=10=], 1, length([=10=])-1); next } 1' <<'EOF'
12345\
6789\
523435\
00000
EOF
产生
12345678952343500000
这表明 3 连续(或更多)行延续工作正常,与问题中的命令不同。
命令解释:
/\$/
匹配一行末尾 ($
) 的\
,表示行继续。substr([=16=], 1, length([=16=])-1)
从输入行[=18=]
. 中删除尾随 - 通过使用
printf "%s"
,(修改后的)当前行打印时没有尾随换行符,这意味着接下来出现的任何打印命令都将直接附加到它后面,有效地将当前行和下一行连接起来。 next
完成当前行的处理。1
是一个常见的awk
习语,它是 shorthand for{ print }
,即,用于简单地打印输入行(尾随\n
).
\
至于为什么原来的命令不起作用:
awk '/\$/ { sub(/\$/,""); getline t; print [=12=] t; next }; 1
- 遇到行继续符(
\
在当前行的末尾),getline t
从文件中读取 next 行并在 current 行之后 按原样 打印它。 next
然后完成对当前和 - 由于getline
调用 - next 行的处理,以便下一个脚本循环处理after 行 next 行(当前行的 2 行)。- 因此,由于通过
getline
读取的行是盲目打印的并且未以任何方式检查,因此在行继续字符处理方面 跳过了 。
一般来说,正如 Ed Morton 在评论中指出的那样,使用 getline
很少是正确的解决方案,并且可能导致细微的错误 - 请参阅 http://awk.info/?tip/getline.