How to insert a newline in front of a pattern?

2019-01-04 17:59发布

Not how to insert a newline before a line. This is asking how to insert a newline before a pattern within a line.

For example,

sed 's/regexp/&\n/g'

will insert a newline behind the regexp pattern.

How can I do the same but in front of the pattern?

Here is an example input file

somevariable (012)345-6789

Should become

somevariable
(012)345-6789

标签: shell sed
16条回答
Anthone
2楼-- · 2019-01-04 18:28

In sed, you can't add newlines in the output stream easily. You need to use a continuation line, which is awkward, but it works:

$ sed 's/regexp/\
&/'

Example:

$ echo foo | sed 's/.*/\
&/'

foo

See here for details. If you want something slightly less awkward you could try using perl -pe with match groups instead of sed:

$ echo foo | perl -pe 's/(.*)/\n$1/'

foo

$1 refers to the first matched group in the regular expression, where groups are in parentheses.

查看更多
再贱就再见
3楼-- · 2019-01-04 18:30

Some of the other answers didn't work for my version of sed. Switching the position of & and \n did work.

sed 's/regexp/\n&/g' 

Edit: This doesn't seem to work on OS X, unless you install gnu-sed.

查看更多
神经病院院长
4楼-- · 2019-01-04 18:31

This works in bash, tested on Linux and OS X:

sed 's/regexp/\'$'\n/g'

In general, for $ followed by a string literal in single quotes bash performs C-style backslash substitution, e.g. $'\t' is translated to a literal tab. Plus, sed wants your newline literal to be escaped with a backslash, hence the \ before $. And finally, the dollar sign itself shouldn't be quoted so that it's interpreted by the shell, therefore we close the quote before the $ and then open it again.

Edit: As suggested in the comments by @mklement0, this works as well:

sed $'s/regexp/\\\n/g'

What happens here is: the entire sed command is now a C-style string, which means the backslash that sed requires to be placed before the new line literal should now be escaped with another backslash. Though more readable, in this case you won't be able to do shell string substitutions (without making it ugly again.)

查看更多
爷的心禁止访问
5楼-- · 2019-01-04 18:31
echo one,two,three | sed 's/,/\
/g'
查看更多
放荡不羁爱自由
6楼-- · 2019-01-04 18:31

You can also do this with awk, using -v to provide the pattern:

awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file

This checks if a line contains a given pattern. If so, it appends a new line to the beginning of it.

See a basic example:

$ cat file
hello
this is some pattern and we are going ahead
bye!
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
hello
this is some 
pattern and we are going ahead
bye!

Note it will affect to all patterns in a line:

$ cat file
this pattern is some pattern and we are going ahead
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' d
this 
pattern is some 
pattern and we are going ahead
查看更多
虎瘦雄心在
7楼-- · 2019-01-04 18:33

In this case, I do not use sed. I use tr.

cat Somefile |tr ',' '\012' 

This takes the comma and replaces it with the carriage return.

查看更多
登录 后发表回答