sed:替换行尾

时间:2013-08-16 10:23:56

标签: bash sed eol

我需要引用行尾和使用this解决方案来替换当文件有多行时完美工作的行尾。

当我尝试将此方法用于没有\n或单行以\n结尾的文件时,会出现问题。在这种情况下,sed不会替换任何内容,即使第二个s/命令也不起作用。看起来像行的最后一行永远不会被替换。

我的命令是:

sed ':a;N;$!ba;s/\n/\\n/g;s/a/_/g' <file>

(将\n替换为\\n并将a替换为_例如。)

我使用hexdump -C在这里显示文件:

我做了一些测试:

$ # Test1. single line without \n
$ echo -n 'abc' | sed ':a;N;$!ba;s/\n/\\n/g;s/a/_/g' | hexdump -C
00000000  61 62 63                                          |abc|
# but expected "_bc"

$ # Test2. single line with \n
$ echo 'abc' | sed ':a;N;$!ba;s/\n/\\n/g;s/a/_/g' | hexdump -C
00000000  61 62 63 0a                                       |abc.|
# but expected "_bc\n"

$ # Test3. two lines
$ echo -e 'abc\n' | sed ':a;N;$!ba;s/\n/\\n/g;s/a/_/g' | hexdump -C
00000000  5f 62 63 5c 6e 0a                                 |_bc\n.|
# but expected "_bc\n\n"

问题:为什么第二个s/不替换Test1和Test2中的任何内容?在所有测试中是否有任何方法可以修复s/\n/\\n/s/a/_/g的替换?

P.S。:我不想要一些解决方法,比如在sed处理之前在流的末尾添加换行符并在之后删除它。

编辑:看起来N命令不会读取单行,即使它后跟'\ n'。知道怎么解决吗?

EDIT2:似乎是expected behavior of N command。有没有关于如何替换最后一行结尾的方法?

3 个答案:

答案 0 :(得分:3)

这可能适合你(GNU sed):

sed ':a;$!{N;ba};s/\n/\\n/g;s/a/_/g' file

或:

sed ':a;$!N;$!ba;s/\n/\\n/g;y/a/_/' file

逻辑上有意义:如果您在next行,则无法获得last行。

答案 1 :(得分:2)

您可以使用perl吗?

$ echo -n "abc" | perl -pe 's/\n$/\\n/;' -pe 's/a/_a/;' | od -x
0000000 615f 6362
0000004
$ echo "abc" | perl -pe 's/\n$/\\n/;' -pe 's/a/_a/;' | od -x
0000000 615f 6362 6e5c
0000006
$ echo -e 'abc\n' | perl -pe 's/\n$/\\n/;' -pe 's/a/_a/;' | od -x
0000000 615f 6362 6e5c 6e5c
0000010

答案 2 :(得分:0)

很遗憾,但是在使用N命令时,我找不到任何方法来阻止sed向输出添加新行。我不想在处理之前添加新行并在之后删除它,但似乎没有其他方法。

这是解决方法的最终解决方案:

sed ':a;$!{N;ba};s/\n/\\n/g;s/a/_/g' <<< "$VAR" | tr -d '\n'

<<<如echo在输入字符串中添加新行,tr将其删除。

使用该行,所有测试都可以:

$ echo -e "abc" | sed ':a;$!{N;ba};s/\n/\\n/g;s/a/_/g' | tr -d '\n' | hexdump -C
00000000  5f 62 63                                          |_bc|

$ echo -e "abc\n" | sed ':a;$!{N;ba};s/\n/\\n/g;s/a/_/g' | tr -d '\n' | hexdump -C
00000000  5f 62 63 5c 6e                                    |_bc\n|

$ echo -e "abc\n\n" | sed ':a;$!{N;ba};s/\n/\\n/g;s/a/_/g' | tr -d '\n' | hexdump -C
00000000  5f 62 63 5c 6e 5c 6e                              |_bc\n\n|

P.S。:感谢potong找出:a;$!{N;ba}

P.P.S。:如果有人在没有tr的情况下给出工作答案,我会重新接受。