1

I have a file like:

file.foo
file2.foo
file.bar
file3.foo

Now I want to return only lines that end with .foo, but I want to rename all occurrences of file with blag. In this case that means skipping over file.bar entirely. How do I go about doing it with just sed? Essentially what I'm doing currently is:

grep '\.foo$' input | sed -e's/file/blag/'

But I would like to cut the grep out.

This question is roughly based on a pipeline I made for this answer

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Evan Carroll
  • 30,763
  • 48
  • 183
  • 315

4 Answers4

3

Or, in mirror form, turn default-printing off, do the replacements, then only print lines you want:

sed -n  's/file/blag/; /\.foo$/p' < input

Or, filter on the desired lines first, then do the replace-and-print:

sed -n '/\.foo$/ { s/file/blag/; p }' < input
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • I think I would go with my own answer because the one that I think answers the title and is what I was looking for is to filter the desired lines first. If there is no implementation differences, I think sed -n '/\.foo$/ { s/file/blag/; p }' is more difficult to follow than sed -e'/\.foo$/!d' -e's/file/blag/' But you still have the upvote. – Evan Carroll Jul 22 '18 at 17:24
1

I was able to get grep out of my pipeline to sed by using !d

sed -e'/\.foo$/!d' -e's/file/blag/' ./input

Answer sourced from this forum post

Evan Carroll
  • 30,763
  • 48
  • 183
  • 315
  • 1
    Because of the lack of anchoring, this would output a line with thefile.food as theblag.food. – Kusalananda Jul 07 '18 at 20:20
  • @Kusalananda yep, fixed -- this is MVP (minimal problem to show an example). As a side note the actual use case needs to be unanchored (link in question) – Evan Carroll Jul 07 '18 at 21:06
0

Select lines that end in .foo and execute a substitution for only those lines:

sed '/\.foo$/{s/file/blag/}'

Testing:

$ echo $'file.foo\nfile2.foo\nfile.bar\nfile3.foo' | sed '/\.foo$/{s/file/blag/}'
blag.foo
blag2.foo
file.bar
blag3.foo
0
sed -n 's/\(file\)\(.*\)\(\.foo\)/blang\2\3/p' input.txt > output.txt

(writes to output file)

OR

sed -i 's/\(file\)\(.*\)\(\.foo\)/blang\2\3/' input.txt 

(in-file replacement)

Glorfindel
  • 815
  • 2
  • 10
  • 19
Nisha
  • 37