Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a newline in front of a pattern?

Tags:

shell

sed

People also ask

How do you insert a sed line after a pattern?

The sed command can add a new line after a pattern match is found. The "a" command to sed tells it to add a new line after a match is found. The sed command can add a new line before a pattern match is found. The "i" command to sed tells it to add a new line before a match is found.

How do you insert a new line character after a fixed number of characters in a file?

@JM88, Unix/Linux use the line-feed character ( \n ) for line breaks. Mac uses the carriage-return character for line breaks ( \r ), and Windows uses a combination of the two ( \r\n ) for line breaks.

How do I insert a blank line in Linux?

*/&\n/' , otherwise you'll insert the newline right after the match instead of at the end of the line. Also note that your solution requires GNU sed (won't work on BSD/OSX, because the BSD sed implementation doesn't support escape sequence \n in the replacement string).


This works in bash and zsh, 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.)


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.


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.


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"

echo one,two,three | sed 's/,/\
/g'

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}'

A couple final thoughts.

using -ne instead of -pe acts similarly, but doesn't automatically print at the end. It can be handy if you want to print on your own. E.g., here's a grep-alike (m/foobar/ is a regex match):

perl -ne 'if (m/foobar/) {print}'

If you are finding dealing with newlines troublesome, and you want it to be magically handled for you, add -l. Not useful for the OP, who was working with newlines, though.

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


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.