Home > database >  How can I replace a character with a defined number of different characters in sed?
How can I replace a character with a defined number of different characters in sed?

Time:05-30

Basic sed question:

This sed substitution works fine to replace a string of Ns with a Z:

cat test1 | sed -E "s/N{10}/Z/g"

But the reverse replaces a Z with the literal string "N{10}"

cat test2 | sed -e "s/Z/N{10}/g"

and returns something like this: AAAA**N{10}**AAAA

How can I replace "Z" with a string of 10 Ns? I know I can key in NNNNNNNNNN into the sed command, but I'm trying to understand the syntax. For some reason N{10} works as in the to-be-replaced but not as replace-with. I've tried to to this a variety of ways, but can't find anything that works.

Any advice will be appreciated.

CodePudding user response:

can do it:

perl -pe 's/Z/N x 10/e' file

With N x 10, you ask explicitly to repeat 1O times N

CodePudding user response:

but I'm trying to understand the syntax

From 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.

Generally & and \1 \2 ... \9 and \\ are "special" in replacement. There is also \n that can be replacement list that is not in POSIX standard, but it is supported in sed implementations. Also https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command .

BRE is:

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: [...]

In regular expression {10} means to match a group repeated 10 times. BRE and replacement have very different rules, and regular expression is used to match, not generate, strings.

I can recommend https://regexcrossword.com/ to learn regex with fun.

CodePudding user response:

Using sed

$ sed "s/Z/echo $(printf -- 'N%.0s' {1..10})/e" input_file
NNNNNNNNNN

CodePudding user response:

Using sed plus bash:

$ echo 'fooNxyzNbar' | sed "s/N/$(printf 'Z%.0s' {1..10})/g"
fooZZZZZZZZZZxyzZZZZZZZZZZbar
  • Related