2

I have an sed question to which I couldn't find the answer anywhere yet:

I have a bunch of files, some of them start with the string ### and some don't. In every file which starts with ### I would like to insert some multi-line string before the current first line.

f.e. If a file looks like

### the first line

abc cba jfkdslfjslkd

I want the multi line string to get inserted at the top

my
multi
line
string

### the first line

abc cba jfkdslfjslkd

Nothing else in the file should get modified.

If a file does not start with ### then I don't want to edit it.

replay
  • 3,569
  • 3
  • 21
  • 30

3 Answers3

2

Using sed

First let's define your string:

$ s='my\nmulti\nline\nstring\n\n'

Now, let's run a sed command:

$ sed "1s/^###/$s&/" File
my
multi
line
string

### the first line

abc cba jfkdslfjslkd

How it works:

  • 1s/old/new/ substitutes new for old but only if old occurs on the first line.

  • 1s/^###/$s&/ substitutes the string $s in front of ### if the first line starts with ###.

Warning: The string s should not contain any sed-active characters. If the string s is not under your control, this is a security violation.

Using awk

Awk has sensible handling of variables and this avoids the security problem.

$ s='my\nmulti\nline\nstring\n'
$ awk -v string="$s" 'NR==1 && /^###/ {print string} 1' File
my
multi
line
string

### the first line

abc cba jfkdslfjslkd
John1024
  • 109,961
  • 14
  • 137
  • 171
0

This may be a simpler solution in sed:

Input:

▶ string='my\nmulti\nline\nstring\n'
▶ cat FILE 
### the first line

abc cba jfkdslfjslkd

### other lines

Solution:

▶ gsed -e '1{/^###/i\' -e "$string" -e '}' FILE
my
multi
line
string

### the first line

abc cba jfkdslfjslkd

### other lines"

Explanation:

  • Use of multiple -e allows us to avoid interpolating strings into the sed command.
  • The GNU alternative form of i\ command as noted in the GNU manual.
Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
0

tried on gnu sed and bash

$ a='my\nmulti\nline\nstring'; echo -e $a
my
multi
line
string

$  sed -Ee "0,/^###/{/^###/i$a" -e '}' file*

my
multi
line
string
### the first line

abc cba jfkdslfjslkd