如何在 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 -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 命令运行所必需的内部替换开关。