Reputation: 119
I have the following input file:
this is text
identifier {
item /directory/file_1234
some more text
item /directory/file_1234 other line text
identifier {
item /directory/98_76file
other line
I want to replace the stings item /directory/*
, that come after the line identifier {
with /directory/file_ABC
I tried
cat input | sed ':a;N;$!ba;s/ identifier {\n item \/directory\/.*$/ identifier {\n newitem \/directory2\/file_ABC/g'
but it erases the lines after the first occurrence
this is text
identifier {
newitem /directory2/file_ABC
Upvotes: 2
Views: 542
Reputation: 58430
This might work for you (GNU sed):
sed -E '/identifier \{/{n;s#(/directory/).*#\1file_ABC#;}' file
Turn on extended regexps by setting -E
.
Match on a line containing identifier {
and print then fetch the next line.
If the line matches /directory/
replace that by itself and file_ABC
.
Upvotes: 2
Reputation: 29212
Your problem comes form the final .*$
of your pattern: in multi-line mode it matches until the end of the pattern space. Try (tested with GNU sed
):
$ sed -E ':a;N;$!ba;s!((^|\n) +identifier \{\n +)item /directory/[^\n]*!\1newitem /directory2/file_ABC!g' input
this is text
identifier {
newitem /directory2/file_ABC
some more text
item /directory/file_1234 other line text
identifier {
newitem /directory2/file_ABC
other line
Note: using cat
to feed sed
is an anti-pattern. Simply sed 'script' file
.
Note: using !
as fields separator of the substitute command instead of /
avoids escapes and using the -E
option simplifies a bit more.
Upvotes: 2
Reputation: 11227
Assuming you want to replace both occurances, you can use this sed
$ sed '/identifier {/{N;s~\(.*\n[^[:alpha:]]*\).*~\1newitem /directory/file_ABC~}' input_file
this is text
identifier {
newitem /directory/file_ABC
some more text
item /directory/file_1234 other line text
identifier {
newitem /directory/file_ABC
other line
Upvotes: 2