我从 shell 脚本调用一个程序,它创建一个具有这种格式的输出文件:
aaaaa\
bbbbb\
ccccc\
我想将其更改为:
aaaaabbbbbccccc
在 VI 编辑器中,我可以这样做ggVGJ
,然后将所有 \ 替换为“”。但我想通过脚本完成这项工作。
这是使用 GNU 的一种方法sed
:
sed ':a; N; $!ba; s/\\\n//g; s/\\$//' file
另一种使用awk
, 可能会给你更好的性能:
awk '{ sub ("\\\\$", ""); printf "%s", $0 } END { print "" }' file
结果:
aaaaabbbbbccccc
解释:
该awk
解决方案删除尾随反斜杠(通过替换)和 printf 的每一行(没有换行符)。END
(在脚本末尾执行)然后打印一个换行符。这优于sed
解决方案,它创建一个名为的标签a
并将下一行输入附加到模式空间中。$!ba
意思是'如果不在输入的最后一行,则分支到标签a
'。然后第一次替换从模式空间中删除每个反斜杠和换行符。第二个替换删除了最后一个尾随反斜杠。这个解决方案对于小文件应该很快,但可能不会比awk
同一个文件快。虽然……写起来更快。
sed
这是使用and的一种方法tr
:
sed 's/\\$//' < sample.txt | tr -d '\n'
如果您也想添加换行符,可以echo
在末尾添加一个:
sed 's/\\$//' < sample.txt | tr -d '\n'; echo
如果您希望整个事物成为一个单元,例如在... && ... || ...
构造中使用,那么您可以将这两个步骤分组,如下所示:
{ sed 's/\\$//' < sample.txt | tr -d '\n'; echo; }
我猜这个解决方案是最小的:
$ cat tmp.txt
aaaaa\
bbbbb\
ccccc\
$ cat tmp.txt | tr -d "\\\r\n"
aaaaabbbbbccccc
另一种方式,使用纯 bash:
$ cat file.txt
aaaaa\
bbbbb\
ccccc\
$ { cat file.txt ; echo; } | while read line; do echo $line; done
aaaaabbbbbccccc
$
这是有效的,因为 bashread
命令实际上自动处理 \ 延续(使用 -r 开关read
来禁用此行为)。echo
后面的是cat
本示例所必需的,因为示例文本的最后一行以 结尾\
,因此 read 命令认为它没有到达行尾并且不输出任何内容。只是在流的echo
末尾插入一个空行来清理它。
试试这条线;
awk -F'\\\\$' '{printf "%s", $1}END{print ""}' file
这是一个非常丑陋的黑客,但你可以使用gcc 预处理器:
$ cat file.txt
aaaaa\
bbbbb\
ccccc\
$ cat file.txt | gcc -xc -E -P -w - | grep .
aaaaabbbbbccccc
$
为什么会有风险?如果您的输入文本碰巧包含预处理器指令,那么它们将被解释,从而导致混乱。
一个awk
和sed
:
sed 's/\\$//g' file | awk '{printf "%s", $1}'
sed
命令删除行尾的斜杠。$
表示斜线后的行尾。由于slash
被视为 中的元字符sed
,因此您需要一个额外的字符\
来转义它。将 sed 的输出通过管道输出以将awk printf
多行合二为一。$0
代表整条线。