Delete all lines starting two lines after / pattern /

Suppose I have a file of the following file:

drink
eat
XXX
pizza
blunzn
sushi

I would like to delete all lines from the file, starting from the third line after the template XXX, so the result should look like this:

drink
eat
XXX
pizza
blunzn

Deleting all the lines after is XXXquite simple:

sed -e '/XXX/q' -i data.txt

However, it is difficult for me to skip a fixed number of lines after deleting the template.

The best I've come up with so far:

 sed -e '/XXX/ { N; N; q }' -i data.txt

Is there anything more elegant than adding n * N(imagine I'd like to skip 50 lines)

+4
source share
5 answers

This may work for you (GNU sed):

sed '/pattern/{:a;N;s/\n/&/2;Ta;q}' file

When you find the desired pattern, loop the desired lines, then close.

, , :

sed '/pattern/{:a;N;s/\n/&/50;Ta;q}' file
+1

awk, n, , , /XXX/:

awk -v n=2 'seen && !n-- { exit } /XXX/ { seen = 1 } 1' file

seen (false) , , !n-- . , seen true.

seen , && , n . n 0, !n , script .

1 , script .

+3

sed - , GNU :

sed '1,/XXX/{/XXX/!b};/XXX/,+2b;d' infile

, :

1,/XXX/ {      # From the first line until the pattern
    /XXX/! b   # Print (by skipping all commands), except when on pattern line
}
/XXX/,+2 b     # For pattern line and the following two, print by skipping commands
d              # Don't print line

GNU /pattern/,+N.

/XXX/! , .

:

n=2
sed "1,/XXX/{/XXX/"\!"b};/XXX/,+${n}b;d" infile

!, .

( ), , , :

sed -n '1,/XXX/{/XXX/!{p;b}};/XXX/,+2{p;b};q' infile
+1
n=3
csplit -s data.txt "/XXX/+${n}"
rm xx01

Your result in xx00. This splits the file by pattern XXX, line offset ${n}, into two files, xx00and the xx01first of which contains what you want. You can change the prefix and / or format of the output files. If you have several XXX, it will generate more files.

+1
source

Bash equivalent of Tom Fenech Elegant awk :

n=2
while IFS= read -r line || [[ -n $line ]]; do 
    if [ $seen ] && ! ((n--)); then
        break
    fi
    if [[ "$line" =~ ^XXX ]]; then 
        seen=1
    fi  
    echo "$line"
done <file   >filtered
0
source

Source: https://habr.com/ru/post/1668639/


All Articles