Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
548 views
in Technique[技术] by (71.8m points)

regex - Insert linefeed in sed (Mac OS X)

How do I insert a newline in the replacement part of sed?

This code isn't working:

sed "s/(1234)/
1/g" input.txt > output.txt

where input.txt is:

test1234foo123bar1234

and output.txt should be:

test
1234foo123bar
1234

but insted I get this:

testn1234foo123barn1234

NOTE:

This question is specifically about the Mac OS X version of "sed", and the community has noted that it behaves differently than, say, Linux versions.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your sed version apparently does not support in RHS (right-hand side of substitution). You should read THE SED FAQ maintained by Eric Pement to choose one of possible solutions. I suggest trying first inserting literal newline character.

Below is the quote from it.


4.1. How do I insert a newline into the RHS of a substitution?

Several versions of sed permit to be typed directly into the RHS, which is then converted to a newline on output: ssed, gsed302a+, gsed103 (with the -x switch), sed15+, sedmod, and UnixDOS sed. The easiest solution is to use one of these versions.

For other versions of sed, try one of the following:

(a) If typing the sed script from a Bourne shell, use one backslash if the script uses 'single quotes' or two backslashes \ if the script requires "double quotes". In the example below, note that the leading > on the 2nd line is generated by the shell to prompt the user for more input. The user types in slash, single-quote, and then ENTER to terminate the command:

 [sh-prompt]$ echo twolines | sed 's/two/& new
 >/'
 two new
 lines
 [bash-prompt]$

(b) Use a script file with one backslash in the script, immediately followed by a newline. This will embed a newline into the "replace" portion. Example:

 sed -f newline.sed files

 # newline.sed
 s/twolines/two new
 lines/g

Some versions of sed may not need the trailing backslash. If so, remove it.

(c) Insert an unused character and pipe the output through tr:

 echo twolines | sed 's/two/& new=/' | tr "=" "
"   # produces
 two new
 lines

(d) Use the G command:

G appends a newline, plus the contents of the hold space to the end of the pattern space. If the hold space is empty, a newline is appended anyway. The newline is stored in the pattern space as where it can be addressed by grouping (...) and moved in the RHS. Thus, to change the "twolines" example used earlier, the following script will work:

 sed '/twolines/{G;s/(two)(lines)(
)/132/;}'

(e) Inserting full lines, not breaking lines up:

If one is not changing lines but only inserting complete lines before or after a pattern, the procedure is much easier. Use the i (insert) or a (append) command, making the alterations by an external script. To insert This line is new BEFORE each line matching a regex:

 /RE/i This line is new               # HHsed, sedmod, gsed 3.02a
 /RE/{x;s/$/This line is new/;G;}     # other seds

The two examples above are intended as "one-line" commands entered from the console. If using a sed script, i immediately followed by a literal newline will work on all versions of sed. Furthermore, the command s/$/This line is new/ will only work if the hold space is already empty (which it is by default).

To append This line is new AFTER each line matching a regex:

 /RE/a This line is new               # HHsed, sedmod, gsed 3.02a
 /RE/{G;s/$/This line is new/;}       # other seds

To append 2 blank lines after each line matching a regex:

 /RE/{G;G;}                    # assumes the hold space is empty

To replace each line matching a regex with 5 blank lines:

 /RE/{s/.*//;G;G;G;G;}         # assumes the hold space is empty

(f) Use the y/// command if possible:

On some Unix versions of sed (not GNU sed!), though the s/// command won't accept in the RHS, the y/// command does. If your Unix sed supports it, a newline after aaa can be inserted this way (which is not portable to GNU sed or other seds):

 s/aaa/&~/; y/~/
/;    # assuming no other '~' is on the line!

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...