1

How can I delete lines in a file until it matches a string line pattern?

cat test.txt
The first line
The second line
The third line
The fourth line
pen test/ut
The sixth line
The seventh line

I would like to use shell/python script to remove all the lines from the above file until it matches the file string pattern "pen test"

Expected output: The file "test.txt" should have only these lines after removing above lines:

The sixth line
The seventh line
JRFerguson
  • 14,740
itgeek
  • 229

5 Answers5

3

With GNU sed: delete everything up to the first match and modify the file in-place:

sed -i '0,/pen test/d' test.txt
1

You can do this:

cat test.txt | grep -A2 "pen test/ut" | sed "1 d"
The sixth line
The seventh line
  • 5
    This assumes that you already know what the content of the file is. In that case, why don't you simply run tail -n 2 infile to get the last two lines instead of using three commands, pipes etc ? – don_crissti Sep 17 '18 at 18:41
  • 1
    @don_crissti . thanks! I am a newbie I still have 304 reputations, give me thumb up ;-) –  Sep 17 '18 at 18:48
  • 2
    Your answers will be upvoted when they are valid. We don't rate people, we rate answers. – xenoid Sep 17 '18 at 20:04
1

You can use utilities sed and Perl to do this as follows:

perl -ne '
  next unless /pen/;  #  skip till we meet the first interesting record
  print <>;           # <> in the list context, fetches the entire remaining file
' input-file.txt

sed -ne '
   /pen/!d
   n
   :loop
      $!N;P;s/.*\n//
   tloop
' input-file.txt

sed -ne '
   /pen/!d  ;# reject lines till we see the first interesting line
   n        ;# skip the first time we see the interesting line
   :n       ;# then setup a do-while loop which"ll do a print->next->print->... till eof
      p;n   ;# the looping ends when the n command tries to read past the last record
   bn
' input-file.txt
0

With Perl:

perl -ni.bck -e '$i++,next if /^pen test/;print if $i' file

This reads your input file and does an in-place update. The original file is preserved with a .bck suffix extension.

As each line of the file is read, a flag, $i, is set if a line begins with pen test and the next line is read. When $i isn't zero (a true condition), lines are printed.

If you only want to extract the lines of interest, and not update, simply do:

perl -ne '$i++,next if /^pen test/;print if $i' file
JRFerguson
  • 14,740
0

After writing a response with a shell script using split and sed, I remembered the shell command csplit (context split).

I saved your text above in /tmp/del.me. The command:

csplit del.me "/pen test/"

splits the original file into two files, one with the text before the match, the other with the text including and following.

host:tmp me$ cat xx01
pen test/ut
The sixth line
The seventh line

If you don't want the match, you can add "+1" to the match argument and it puts the matched text in the first file.

csplit del.me "/pen test/+1"

So, the above command gives me two output files xx00 xx01. (You can change the file naming.) xx01 contains:

host:tmp me$ cat xx01
The sixth line
The seventh line