我从 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代表整条线。