我需要引用行尾,并使用此解决方案来替换行尾,当文件有多行时,它可以完美地工作。
当我尝试对没有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
的情况下给出有效答案,我会重新接受。