93

I'm new to sed and I have the following question. In this example:

some text here
blah blah 123
another new line
some other text as well
another line

I want to delete all lines except those that contain either string 'text' and or string 'blah', so my output file looks like this:

some text here
blah blah 123
some other text as well

Any hints how this can be done using sed?

2
  • 6
    Must the answer use sed? grep would do this very easily. Commented Mar 2, 2012 at 23:48
  • 1
    askubuntu.com/a/847004/638128 Commented May 12, 2020 at 0:57

4 Answers 4

130

This might work for you:

sed '/text\|blah/!d' file
some text here
blah blah 123
some other text as well
Sign up to request clarification or add additional context in comments.

4 Comments

How can I for example specify that text or blah could only appear in the last column ?
@lovedynasty If you mean at the end of line, you should use $: '/text$\|blah$/!d'
@potong This does not work if I replace the separator char / with #, any idea why?
@burglarhobbit I presume you mean the regexp delimiter /. This may be set to any delimiter in the substitution command e.g. s#...#...# However when used for matching the first delimiter must be quoted e.g set delimiter to # use \#match#d to delete lines that match.
19

You want to print only those lines which match either 'text' or 'blah' (or both), where the distinction between 'and' and 'or' is rather crucial.

sed -n -e '/text/{p;n;}' -e '/blah/{p;n;}' your_data_file

The -n means don't print by default. The first pattern searches for 'text', prints it if matched and skips to the next line; the second pattern does the same for 'blah'. If the 'n' was not there then a line containing 'text and blah' would be printed twice. Although I could have use just -e '/blah/p', the symmetry is better, especially if you need to extend the list of matched words.

If your version of sed supports extended regular expressions (for example, GNU sed does, with -r), then you can simplify that to:

sed -r -n -e '/text|blah/p' your_data_file

9 Comments

If sed does not support -r it probably won't support {} either. This should work with older seds: sed '/text\|blah/!d' file
The { ... } grouping of commands was in 7th Edition UNIX version of sed; I can't think how you'd come across a version where that was not suppported.
I found this easier sed -n -e '/keep-this/p' -e '/keep-that/p' -e '/keep-those/p'. No compound command required. No problems with "line would be printed twice". Additionally, in my case, adding the extra command n in {p;n;} would drop the first expression match. This may have been due to the particular input string. But this answer really helped me find where to look!
@JamesThomasMoon1979 — Be wary of a line that contains "keep-this" he said, and "keep-that", not to mention "keep-those". Your version will print the line three times; mine just once. It depends on your required output. If you want the single line printed three times, your solution is good. If not, then it leaves something to be desired.
Great feedback. In my case, I ran into this error scenario: Given I want to print both input lines a and a b, the following command only prints the first input line echo -e 'a\na b' | sed -n -e '/b/{p;n;}' -e '/a/{p;n;}'. But if I change the order of expressions, the command will print both input lines echo -e 'a\na b' | sed -n -e '/a/{p;n;}' -e '/b/{p;n;}'.
|
12

You could simply do it through awk,

$ awk '/blah|text/' file
some text here
blah blah 123
some other text as well

Comments

1

Are you looking for the grep? Here is an example to look for different texts.

cat yourfile.txt | grep "text\|blah"

2 Comments

This worked perfectly and was the simplest solution among all the other answers. Props.
Even simpler with just grep "text\|blah" > your_new_file.txt!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.