0

There is one text file.(test.txt)

1970-01-01
1971-01-01
1972-01-01
1973-01-01
1974-01-01
....
1993-01-01
1994-01-01
1995-01-01
1996-01-01
...
2015-01-01
2016-01-01

I would like to clear the line of text above in 1995 from 1970 .

Below is the sed command that I made.

sed -i '/197[0-9]/d' test.txt
sed -i '/198[0-9]/d' test.txt
sed -i '/199[0-5]/d' test.txt

Is there a way to use the three commands into one command sed?

8

Since your file appears to be in sorted order, you can just delete from the beginning until the end

eg

sed -i '1,/^1995/d' test.txt

If the date starts before 1970, then

sed -i '/^1970/,/^1995/d' test.txt

If your file isn't in order then there's no easy regex (there's a long boring one) that'll match all the lines, but you can specify multiple

sed -i -e '/^19[78][0-9]/d' -e '/^199[0-5]/d' test.txt
  • Queue long boring regex sed -e '/^19\([7-8][0-9]\|9[0-5]\)/d' test.txt – Zachary Brady Aug 30 '16 at 3:45
  • @Zachary, not all sed implementations support \|. That's not a standard BRE operator. Some sed implementations support -E to use EREs instead of BREs but that's not standard either. – Stéphane Chazelas Aug 30 '16 at 6:40
3

When arithmetic is involved, it is often easier to use awk. For example, to print all lines except the ones with years between 1970 and 1995:

$ awk -F- '$1<1970 || $1 > 1995' test.txt
....
1996-01-01
...
2015-01-01
2016-01-01

Here, -F- tells awk to use - as the field separator. This means that the first field, denoted $1, will be the year.

Unlike sed, awk does math. Thus, $1<1970 is true if the year is less than 1970. $1 > 1995 is true if the year is greater than 1995. || combines those two conditions with a logical-OR. Thus, $1<1970 || $1 > 1995 is true for the years that you want to keep.

-1

You can combine the three into a single regular expression.

sed -i '/19[789][0-9]/d' test.txt

The third character is checked for '7', '8', or '9'.

You might also want to add an anchor for the beginning of the line.

sed -i '/^19[789][0-9]/d' test.txt

This is to prevent it deleting lines where '1970' or '1987' appear in the middle of the line. You (usually) want the regular expression to be as narrow as possible, so it takes only what you wish.

  • 3
    I want to be 1996-1999 remains . "sed -i '/19[789][0-9]/d' test.txt" to delete is 1996-1999 . – DonBit Aug 30 '16 at 1:55

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.