Friday, October 10, 2014

Print all lines after a match up to the end of the file

Very useful thing in __DATA__ analog in shell scripts, e.g.:
#!/bin/sh

# do something with data after exit 0
exit 0
# list of things:
thing 1
thing 2
thing 3
To iterate over things, one could use known size of the list:
tail -3 $0 | (while read name size; do 
    echo $name $size
done)
But if this list changes from time to time, you need to adjust tail and once you can forget it. I use unique marker that indicates that everything after it can be used as data. To show everything after match to the end of file, I use the following construction:
#!/bin/sh

sed '0,/^# list of things:$/d' | (while read name size; do 
    echo $name $size
done)
exit 0
# list of things:
thing 1
thing 2
thing 3
It works with GNU sed. You can also use Perl one-liner that works in the same way:
#!/bin/sh

perl -ne 'print unless 1.../^# list of things:$/' $0 | (while read name size; do 
    echo $name $size
done)
exit 0
# list of things:
thing 1
thing 2
thing 3
But experiments show that sed works a bit faster.
From my answer.