-2

Eg:

Content of a file xx.txt is:

Hi
How Are You Doing
Its Been Long Time
Hope Everything Is Fine

So if i need to remove the lines which contain word Doing or Fine.

The output of the file xx.txt must look like:

Hi
Its Been Long Time

Is it possible to do this using a single sed or awk command?

  • Please show us what have you tried so far to solve your problem – mrc02_kr Nov 14 '19 at 7:22
  • What should happen to a line containing either of the words Finer or Doings? – Kusalananda Nov 17 '19 at 9:56
0

Try this,

To print the output:

sed '/Doing\|Fine/d' xx.txt 

To remove the line directly in a file:

sed -i '/Doing\|Fine/d' xx.txt 
  • Thank you very much it worked :) – Sai Nishant Prabhakar Nov 14 '19 at 7:15
  • 1
    If the answer worked for you, please consider accepting if (click on the grey check mark below the vote counter) so that others with similar questions may find it more easily. – AdminBee Nov 14 '19 at 8:47
0
grep -vE "Doing|Fine" xx.txt 

it will print all the lines which is not having the "Doing and Fine" word

  • "Substrings" not "words". To match words, use -w with grep. – Kusalananda Nov 17 '19 at 10:04
0
awk '$0 !~/Fine|Doing/' i.txt  

ouput

Hi
Its Been Long Time
  • As in the other answer Kusalananda pointed out, it will match substring not word. – Prvt_Yadav Nov 17 '19 at 10:24
0

To remove all lines that has the words Doing or Fine in them, you may use grep in the following manner:

grep -Fw -v -e 'Doing' -e 'Fine' file

The -F option makes grep use the given expressions as strings rather than as regular expressions, while -w makes it match whole words (not substrings of other words, like Doings or Fines). The -v option inverts the sense of the test so that lines matching the given expressions are removed from the output. The two strings are given with -e, which is used to give the expression to query with (this option is often left out, but is needed here as we have two of them).


With sed, you could do

sed -e '/\<Doing\>/d' -e '/\<Fine\>/d' file

or

sed '/\<Doing\>/d; /\<Fine\>/d' file

or

sed -E '/\<(Doing|Fine)\>/d' file

Each of of these matches the two string as words. The \< and \> special patterns matches the zero-width space at the beginning and end of a word respectively (the space between a word-character and a non-word-character). With GNU sed, you could use \b in place of both \< and \>.

The last sed command uses an alternation to match either word. Alternations is a feature of extended regular expressions, so we enable these using -E on the command line.

In all cases, the pattern is matched against every line of input, and if it matches, it is deleted with the d command. All other lines are printed.

The inverse, printing all lines that does not match, and ignoring the rest, could be done with

sed -n -E '/\<(Doing|Fine)\>/!p' file

That is, turn off the default outputting of the data with -n and then only print (p) the lines that does not match (!) the pattern.


The awk code would look very similar to the sed code using extended regular expressions, at least if using GNU awk (which understands \< and \>):

awk '!/\<(Doing|Fine)\>/' file

or

awk '!/\<Doing\>/ && !/\<Fine\>/' file

These both tries to match the two words against the input data, and would not print the data if the words are present.

You may also use the index() function in awk, but this would also find the words as substrings (just like using /(Doing|Fine)/ would do):

awk '!index($0, "Doing") && !index($0, "Fine")' file

index($0, string) returns zero if the string is not found in $0 (the whole line), so negating the result with ! would give you a true value if the string wasn't found.

The long-handed way to do it in awk is to check every field separately:

awk '{ for (i = 1; i <= NF; ++i) if ($i == "Doing" || $i == "Fine") next; print }' file

This tests each field against the two words and skips immediately to the next input line if one of them is found. Otherwise, the line is printed.

This would give different results from using /\<(Doing|Fine)\>/ if a word like A-Doing was present in the text. The loop would not spot it (because the fields are divided on whitespace), but the regular expression would (because - is a non-word-character).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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