0

I've got a text file containing

Today, 12:34https://...
Today, 12:43https://...
Yesterday, 13:21https://...
Nottoday, 12:32https://

and would like to delete all lines that do not match with "Today" or "Yesterday".

I found a sed command here in this forum with only one pattern and tried out the following for a text file only containing Today lines:

sed -n '/Yesterday/p' file.txt

or

sed '/Yesterday/!d' file.txt

but it won't delete anything. Can you help me out how to eliminate all lines not containing "Today" or "Yesterday"?

  • Are you expecting the original file to change? – Kusalananda Sep 2 '20 at 12:43
  • Try this with GNU sed: sed -E '/(Today|Yesterday)/!d' filename – Rakesh Sharma Sep 2 '20 at 12:48
  • Yes, the original file should change and only contain lines with "Today" or "Yesterday" after the command. Sorry, didn't mention that. – X3nion Sep 2 '20 at 12:55
2

Sed does not modify your files (unless given the -i flag, for implementations that provide it). It reads the file and write to standard output, as can be seen below.

$ sed -n '/Yesterday/p' file.txt
Yesterday, 13:21https://...
$ cat file.txt
Today, 12:34https://...
Today, 12:43https://...
Yesterday, 13:21https://...
Nottoday, 12:32https://

To delete all lines not matching Today nor Yesterday, you can use the Ed editor.

printf '%s\n' 'v/Today\|Yesterday/d' w q | ed -s file.txt

v is the reverse global command, so d deletes all lines not matching Today or Yesterday. w writes the changes and q quits. The -s flag to Ed runs it in silent mode.

You can also use Sed with the -i flag,

sed -n -i '/Yesterday\|Today/p' file.txt
1

To edit the file in place with sed, you need the non-standard -i option:

# GNU syntax à la perl (now also in busybox, NetBSD, OpenBSD):
sed -i -e /Yesterday/b -e /Today/b -e d your-file

# FreeBSD syntax (also in derivatives like macOS):
sed -i '' -e /Yesterday/b -e /Today/b -e d your-file

The b sed command branches out (equivalent of next/continue in some other languages), while d deletes the pattern space (which ends up not being printed). So we delete all but the lines that either contain Yesterday or Today.

Or use perl (whose -i some sed implementations borrowed):

perl -i -ne 'print if /(Yester|To)day/' your-file

Standard basic regular expressions as used by sed or ed don't have a | alternation operator, however several sed implementations have a -E to switch to extended regular expressions (that option will also be in the next version of the POSIX specification for sed (not ed)).

sed -Ei '/(Yester|To)day/!d' your-file

The GNU implementation of sed also supports \| as an alternation operator in its basic regular expressions (without -E/-r):

sed -i '/\(Yester\|To\)day/!d' your-file
0

Done by 2 methods awk and python

command

 awk '!/Today|Yesterday/' filename

output

Nottoday, 12:32https:

Python

#!/usr/bin/python
import re
h=re.compile(r'Today|Yesterday')
k=open('p','r')
for i in k:
    if not re.search(h,i):
        print i.strip()

output

Nottoday, 12:32https:
  • You have it the other way round. The lines with Today and Yesterday should be kept. – Quasímodo Sep 4 '20 at 15:08

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.