为什么 sed 不替换 NULL 字符 \x0?
Why sed doesn't replace NULL-characters \x0?
如果我想替换几行,例如在文件或 STDIN 中,并且我不知道文件或 STDIN 中出现的行数,我可以将整个流程合并为一个行,例如 tr
,像这样:
$ printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=10=]' | sed -e 's#bbb\x0ccc\x0ddd#string2\x0string3\x0string4#g' | tr '[=10=]' '\n'
aaa
bbb
ccc
ddd
我想在这种情况下得出这样的结论:
aaa
string2
string3
string4
请注意,这是一个测试示例,在实际情况下,我不知道要进行替换的行数。我只知道需要替换的行和需要替换的行。
据我所知,sed
可以替换NULL字符,例如:
printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=12=]' | sed -e 's#\x0#\n#g'
aaa
bbb
ccc
ddd
为什么第一种情况没有发生?
你可以尝试用正则表达式替换它 - (.*)
而不是\x0
,但是输入数据不同,它会导致替换错误,如下例:
$printf "%s\n" aaa bbb ccc ddd bbb ddd | tr '\n' '[=13=]' | sed -e 's#bbb\(.*\)ccc\(.*\)ddd#string2string3string4#g' | tr '[=13=]' '\n'
aaa
string2
string3
ddd
bbb
string4
你能告诉我如何正确替换多行吗?感谢您的帮助!
问题似乎是 \x
转义消耗的不仅仅是 1 零。
考虑在 \x0c
中,0
和 c
都是有效的十六进制数字。
十六进制转义的工作方式因语言而异。
例如,在 C 语言中,它们超级贪婪(将尽可能消耗所有有效的十六进制数字)。
非宽字符串的更明智的 \x
转义将恰好消耗两位数(以便填充一个 8 位字节)。 Sed 的版本似乎是这样工作的。
根据实验,将 \x0
替换为 \x00
有效:
printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=10=]' | sed -e 's#bbb\x00ccc\x00ddd#string2\x00string3\x00string4#g' | tr '[=10=]' '\n'
如果我想替换几行,例如在文件或 STDIN 中,并且我不知道文件或 STDIN 中出现的行数,我可以将整个流程合并为一个行,例如 tr
,像这样:
$ printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=10=]' | sed -e 's#bbb\x0ccc\x0ddd#string2\x0string3\x0string4#g' | tr '[=10=]' '\n'
aaa
bbb
ccc
ddd
我想在这种情况下得出这样的结论:
aaa
string2
string3
string4
请注意,这是一个测试示例,在实际情况下,我不知道要进行替换的行数。我只知道需要替换的行和需要替换的行。
据我所知,sed
可以替换NULL字符,例如:
printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=12=]' | sed -e 's#\x0#\n#g'
aaa
bbb
ccc
ddd
为什么第一种情况没有发生?
你可以尝试用正则表达式替换它 - (.*)
而不是\x0
,但是输入数据不同,它会导致替换错误,如下例:
$printf "%s\n" aaa bbb ccc ddd bbb ddd | tr '\n' '[=13=]' | sed -e 's#bbb\(.*\)ccc\(.*\)ddd#string2string3string4#g' | tr '[=13=]' '\n'
aaa
string2
string3
ddd
bbb
string4
你能告诉我如何正确替换多行吗?感谢您的帮助!
问题似乎是 \x
转义消耗的不仅仅是 1 零。
考虑在 \x0c
中,0
和 c
都是有效的十六进制数字。
十六进制转义的工作方式因语言而异。
例如,在 C 语言中,它们超级贪婪(将尽可能消耗所有有效的十六进制数字)。
非宽字符串的更明智的 \x
转义将恰好消耗两位数(以便填充一个 8 位字节)。 Sed 的版本似乎是这样工作的。
根据实验,将 \x0
替换为 \x00
有效:
printf "%s\n" aaa bbb ccc ddd | tr '\n' '[=10=]' | sed -e 's#bbb\x00ccc\x00ddd#string2\x00string3\x00string4#g' | tr '[=10=]' '\n'