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条回答
劫难
2楼-- · 2019-01-04 18:33
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\1/'

worked fine on El Captitan with () support

查看更多
太酷不给撩
3楼-- · 2019-01-04 18:33

In vi on Red Hat, I was able to insert carriage returns using just the \r character. I believe this internally executes 'ex' instead of 'sed', but it's similar, and vi can be another way to do bulk edits such as code patches. For example. I am surrounding a search term with an if statement that insists on carriage returns after the braces:

:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/

Note that I also had it insert some tabs to make things align better.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-04 18:35

Hmm, just escaped newlines seem to work in more recent versions of sed (I have GNU sed 4.2.1),

dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar
查看更多
我命由我不由天
5楼-- · 2019-01-04 18:36

You can use perl one-liners much like you do with sed, with the advantage of full perl regular expression support (which is much more powerful than what you get with sed). There is also very little variation across *nix platforms - perl is generally perl. So you can stop worrying about how to make your particular system's version of sed do what you want.

In this case, you can do

perl -pe 's/(regex)/\n$1/'

-pe puts perl into a "execute and print" loop, much like sed's normal mode of operation.

' quotes everything else so the shell won't interfere

() surrounding the regex is a grouping operator. $1 on the right side of the substitution prints out whatever was matched inside these parens.

Finally, \n is a newline.

Regardless of whether you are using parentheses as a grouping operator, you have to escape any parentheses you are trying to match. So a regex to match the pattern you list above would be something like

\(\d\d\d\)\d\d\d-\d\d\d\d

\( or \) matches a literal paren, and \d matches a digit.

Better:

\(\d{3}\)\d{3}-\d{4}

I imagine you can figure out what the numbers in braces are doing.

Additionally, you can use delimiters other than / for your regex. So if you need to match / you won't need to escape it. Either of the below is equivalent to the regex at the beginning of my answer. In theory you can substitute any character for the standard /'s.

perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'

Bonus tip - if you have the pcre package installed, it comes with pcregrep, which uses full perl-compatible regexes.

查看更多
来,给爷笑一个
6楼-- · 2019-01-04 18:36

This works in MAC for me

sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt

Dono whether its perfect one...

查看更多
女痞
7楼-- · 2019-01-04 18:40

On my mac, the following inserts a single 'n' instead of newline:

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

This replaces with newline:

sed "s/regexp/\\`echo -e '\n\r'`/g"
查看更多
登录 后发表回答