was writing a bash script to delete an entire line from a file if a particular string is found. Let the file be like

this is the first line

second line fast and furious

how faster are you?

its really amaizing

and the output file should be the following if "fast" is the word specified.

this is the first line

its really amaizing

closed as not a real question by womble, Iain Jul 2 '12 at 10:07

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Do your files really have a blank line between each line of text - it really matters ? What have you tried and what didn't work? – Iain Jul 2 '12 at 7:11
  • If you edit your question to make more sense then please flag for it to be reopened. – Iain Jul 2 '12 at 10:07
  • Use the code button or indent sample data lines using 4 spaces or highlight the text and press Ctrl-k and you won't have to double-space to preserve line breaks. – Dennis Williamson Jul 2 '12 at 18:56

If your input file is as you specify and your expected output is as you specify then

sed '/fast/d' filename |  cat -s

will do what you want. The cat -s is used to suppress the blank lines that are generated by sed with your provided input.

You could also do

sed '/fast/d' filename|awk '/^$/{ if (! blank++) print; next }{ blank=0; print }'

If your input text isn't double spaced then

sed '/fast/d' filename

will work.

  • You are missing some closing quotes but I can't edit since the change is less than 6 characters (first and second sed expression) – Matteo Jul 2 '12 at 8:01

You can use sed

$ sed -e "/fast/d" filename

or if you want to edit the file in-place

$ sed -i -e "/fast/d/" filename

Short explanation:

  • -e specifies that the next argument is a command

  • "/fast/" is a regular expression specifying the pattern you are looking for

  • d is the command to delete

  • That doesn't give the OPs expected output. You get the first line followed by 3 blank lines, then the last line. – Iain Jul 2 '12 at 7:08
  • @lain the OP asked to delete lines with a word in it. Blank lines are not touched. He just formatted his question badly (instead of formatting the text lines he put some ----- in front of it). – Matteo Jul 2 '12 at 7:17
  • 2
    No, he says the output file should be the following and gives an example. It may be poor formatting on their part but until they say otherwise we shouldn't assume, as, as you'll be aware it makes a difference. – Iain Jul 2 '12 at 7:26
  • @lain he also says "to delete an entire line from a file if a particular string is found". He never says "and blank lines should be deleted". The question and the example are not consistent. – Matteo Jul 2 '12 at 8:00

Use sed for this

$ sed -e "/fast/d" sample.txt > tmp 
$ mv tmp sample.txt 

Use perl one liner

$ perl -ni.bak -e 'print unless /fast/' sample.txt

This will create backup of sample.txt and delete line containing 'fast ' keyword

  • This doesn't give the OPs expected output as per the question. – Iain Jul 2 '12 at 7:39

Another version that produces your output from your input (i.e. deleting the blank line after the fast as well.)

sed -in 'N; s/.*fast.*$//; /./p;' filename

I'm not sure but I think this will work too:

sed -i 'N; /fast/d' filename

The N; command combines two lines into one pattern space in sed. You can then write regexes that match strings that span two lines. The -n option tells sed not to automatically print lines that match the regex and the /./p; command at the end prints any line that is not the empty string (i.e. whatever is left that we haven't deleted with the first regex). Don't forget if you do this that the \n is still part of the pattern space and needs to be matched. I've used .* in my first example for this.

The existing answers work fine if there are no blank lines in your input or output.

It turns out now that I've tested it that the first version of the first option was problematic. The updated version works. The second option (the one I wasn't sure about) worked perfectly the first time.

Not the answer you're looking for? Browse other questions tagged or ask your own question.