如何在 sed 中用定义数量的不同字符替换一个字符?
How can I replace a character with a defined number of different characters in sed?
基础sed
问题:
这个 sed
替换可以很好地用 Z 替换一串 Ns:
cat test1 | sed -E "s/N{10}/Z/g"
但反向替换 Z 为文字字符串“N{10}”
cat test2 | sed -e "s/Z/N{10}/g"
和 returns 是这样的:AAAA**N{10}**AAAA
如何用 10 N 的字符串替换“Z”? 我知道我可以在 sed
命令中输入 NNNNNNNNNN
,但是我试图理解语法。出于某种原因,N{10}
的工作方式与待替换的一样,但不是替换为。我尝试了多种方法,但找不到任何有效的方法。
如有任何建议,我们将不胜感激。
but I'm trying to understand the syntax
来自 https://pubs.opengroup.org/onlinepubs/009604499/utilities/sed.html:
s/BRE/replacement/flags
Substitute the replacement string for instances of the BRE in the pattern space. [...]
The replacement string shall be scanned from beginning to end. An ampersand ( '&' ) appearing in the replacement shall be replaced by
the string matching the BRE. The special meaning of '&' in this context can be suppressed by preceding it by a backslash. The characters "\n", where n is a digit, shall be replaced by the text matched by the corresponding backreference expression. The special meaning of "\n" where n is a digit in this context, can be suppressed by preceding it by a backslash. For each other backslash ( '\' ) encountered, the following character shall lose its special meaning (if any). The meaning of a '\' immediately followed by any character other than '&', '\', a digit, or the delimiter character used for this command, is unspecified.
一般来说&
和</code><code>
...</code>和<code>\
在替换中是“特殊”的。还有 \n
可以是不在 POSIX 标准中的替换列表,但它在 sed
实现中受支持。还有 https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command .
BRE
是:
The sed utility shall support the BREs described in the Base Definitions volume of IEEE Std 1003.1-2001, Section 9.3, Basic Regular Expressions, with the following additions: [...]
在正则表达式中{10}
表示匹配一组重复10次。 BRE 和替换有非常 不同的规则,正则表达式用于匹配,而不是生成字符串。
我可以推荐 https://regexcrossword.com/ 来有趣地学习正则表达式。
perl可以做到:
perl -pe 's/Z/"N" x 10/ge' file
使用 N x 10
,您明确要求重复 10 次 N
使用sed
$ sed "s/Z/echo $(printf -- 'N%.0s' {1..10})/e" input_file
NNNNNNNNNN
使用 sed 加 bash:
$ echo 'fooNxyzNbar' | sed "s/N/$(printf 'Z%.0s' {1..10})/g"
fooZZZZZZZZZZxyzZZZZZZZZZZbar
这可能适合您 (GNU sed):
sed -E ':a;/Z/{G;s/\n/&/10;Ta;s/Z([^\n]*)(\n.*)//;y/\n/N/;ta}' file
如果一行与所需的字符相匹配。将所需换行符的数量附加到该行的末尾。
然后用换行符替换匹配项,最后将换行符转换为所需格式。
如有必要请重复。
N.B。 t
命令重置了 T
命令运行所必需的内部替换开关。
基础sed
问题:
这个 sed
替换可以很好地用 Z 替换一串 Ns:
cat test1 | sed -E "s/N{10}/Z/g"
但反向替换 Z 为文字字符串“N{10}”
cat test2 | sed -e "s/Z/N{10}/g"
和 returns 是这样的:AAAA**N{10}**AAAA
如何用 10 N 的字符串替换“Z”? 我知道我可以在 sed
命令中输入 NNNNNNNNNN
,但是我试图理解语法。出于某种原因,N{10}
的工作方式与待替换的一样,但不是替换为。我尝试了多种方法,但找不到任何有效的方法。
如有任何建议,我们将不胜感激。
but I'm trying to understand the syntax
来自 https://pubs.opengroup.org/onlinepubs/009604499/utilities/sed.html:
s/BRE/replacement/flags
Substitute the replacement string for instances of the BRE in the pattern space. [...]
The replacement string shall be scanned from beginning to end. An ampersand ( '&' ) appearing in the replacement shall be replaced by the string matching the BRE. The special meaning of '&' in this context can be suppressed by preceding it by a backslash. The characters "\n", where n is a digit, shall be replaced by the text matched by the corresponding backreference expression. The special meaning of "\n" where n is a digit in this context, can be suppressed by preceding it by a backslash. For each other backslash ( '\' ) encountered, the following character shall lose its special meaning (if any). The meaning of a '\' immediately followed by any character other than '&', '\', a digit, or the delimiter character used for this command, is unspecified.
一般来说&
和</code><code>
...</code>和<code>\
在替换中是“特殊”的。还有 \n
可以是不在 POSIX 标准中的替换列表,但它在 sed
实现中受支持。还有 https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command .
BRE
是:
The sed utility shall support the BREs described in the Base Definitions volume of IEEE Std 1003.1-2001, Section 9.3, Basic Regular Expressions, with the following additions: [...]
在正则表达式中{10}
表示匹配一组重复10次。 BRE 和替换有非常 不同的规则,正则表达式用于匹配,而不是生成字符串。
我可以推荐 https://regexcrossword.com/ 来有趣地学习正则表达式。
perl可以做到:
perl -pe 's/Z/"N" x 10/ge' file
使用 N x 10
,您明确要求重复 10 次 N
使用sed
$ sed "s/Z/echo $(printf -- 'N%.0s' {1..10})/e" input_file
NNNNNNNNNN
使用 sed 加 bash:
$ echo 'fooNxyzNbar' | sed "s/N/$(printf 'Z%.0s' {1..10})/g"
fooZZZZZZZZZZxyzZZZZZZZZZZbar
这可能适合您 (GNU sed):
sed -E ':a;/Z/{G;s/\n/&/10;Ta;s/Z([^\n]*)(\n.*)//;y/\n/N/;ta}' file
如果一行与所需的字符相匹配。将所需换行符的数量附加到该行的末尾。
然后用换行符替换匹配项,最后将换行符转换为所需格式。
如有必要请重复。
N.B。 t
命令重置了 T
命令运行所必需的内部替换开关。