sed:替换行尾



我需要引用行尾,并使用此解决方案来替换行尾,当文件有多行时,它可以完美地工作。

当我尝试对没有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 "_bcn"
$ # Test3. two lines
$ echo -e 'abcn' | sed ':a;N;$!ba;s/n/\n/g;s/a/_/g' | hexdump -C
00000000  5f 62 63 5c 6e 0a                                 |_bcn.|
# but expected "_bcnn"

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

附言:我不想要一些变通方法,比如在sed处理之前在流的末尾添加换行符,然后删除它。

EDIT:看起来N命令不读取单行,即使它后面跟有'\n'。知道怎么修吗?

EDIT2:这似乎是N命令的预期行为。关于如何替换最后一行的结尾,有什么方法吗?

这可能对你有用(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

从逻辑上讲,这是有道理的:如果你在last线上,就无法获得next线。

您可以使用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 'abcn' | perl -pe 's/n$/\n/;' -pe 's/a/_a/;' | od -x
0000000 615f 6362 6e5c 6e5c
0000010

Sad,但当使用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 "abcn" | sed ':a;$!{N;ba};s/n/\n/g;s/a/_/g' | tr -d 'n' | hexdump -C
00000000  5f 62 63 5c 6e                                    |_bcn|
$ echo -e "abcnn" | sed ':a;$!{N;ba};s/n/\n/g;s/a/_/g' | tr -d 'n' | hexdump -C
00000000  5f 62 63 5c 6e 5c 6e                              |_bcnn|

附言:感谢波通计算出:a;$!{N;ba}

附言:如果有人在没有tr的情况下给出有效答案,我会重新接受。

最新更新