0

I have a file with lines :

1
apple
2
orange
3
banana
4
mango
5
coconut

I have a list of patterns :

1
3
5

I want to delete the lines (and one additional line after) using the list of patterns, in order to get :

2
orange
4
mango

Since I have a large number of patterns that I could not type manually one by one in a single command, a list must be used.

0

sed + paste solution:

sed -E "/\<(`paste -s -d'|' patterns`)\>/{N;d;}" file

The output:

2
orange
4
mango

  • paste -s -d'|' patterns - merge lines of file patterns using | as a dilimiter to get the regex alternation group (1|3|5)

  • N - append the next line to the pattern space

  • d - delete lines of pattern space

  • This works for the given example, but would remove 10 lemon as well. – Philippos Jul 13 '17 at 10:23
  • @Philippos, ok, see my update – RomanPerekhrest Jul 13 '17 at 11:20
  • Should work now, at least for sed versions supporting \< \>. – Philippos Jul 13 '17 at 11:38
  • @JohnnyTam, you're welcome – RomanPerekhrest Jul 14 '17 at 14:13
0

Let's do some grep option juggling:

You could grep for all lines in your fruit file except for those in your list file with numbers to be excluded:

grep -v -x -f numbers fruits

(-f to give a pattern file, -x to prevent partly matches and -v to invert the match)

Unfortunally, the numbers and the fruits are on separate lines, so the fruits survive the grep. Let's get rid of them with an additional -e pattern:

grep -v -x -e "[a-z]*" -f numbers fruits

Now all lines consisting of letters only are removed, so no fruits anymore, not even the wanted ones. But we can recover them from the context:

grep -v -x -A1 -e "[a-z]*" -f numbers fruits

(-A1 gives an additional line after every match) finally gives what you wanted.

  • I tried RomanPerekhrest's solution and it worked already. Thank you so much! – Johnny Tam Jul 14 '17 at 14:12
0

Try this .

The pattern_file has all your patterns and the rest content in file_content. Here I tried grep with option -A 1 which can change depending on number of lines after patter match.

#!/bin/bash

while read pattern 
do
        for line_num in `grep $pattern file_content -A 1 -n | awk -F":|-" '{print $1}' | paste -sd ","`
        do
                sed -i "${line_num}d" file_content
        done
done < pattern_file
  • I tried RomanPerekhrest's solution and it worked already. Thank you so much! – Johnny Tam Jul 14 '17 at 14:12

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.