Sign up ×

I'm looking for a simple way to utilize regex in a UNIX shell script where not every system will have perl extensions built into grep. What is really helpful about perl regex here is back/forward references which I haven't found a way to use effectively in sed. I've quickly come up with the following 1 liner:

tail --bytes=+K something.log| perl -e 'while (my $line = <STDIN>){if ($line =~ /$ARGV[0]/){print $line};}' 'my regex'

Q1. Is this a safe way to do things for perl? Q2. Should I just resort to writing the entire script in perl instead?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

I don't understand why your perl snippet is written this way. You could write the regexp directly inside the script:

perl -e 'while (my $line = <STDIN>) {if ($line =~ /my regex/) {print $line}}'

which allows you to take advantage of the -n option (as a bonus, you get proper error reporting in case there's an input error). Further using perl idioms:

perl -ne 'print if /my regex/'

Sed has backreferences, but perl's extended regexes are more powerful, there are things you can't do with sed (sed doesn't even have complete regexes: alternation \| is not a standard feature, though many implementations have it).

Most of what you can do with traditional tools, you can do easily in perl. For example, if you want to skip the first K-1 bytes, you can write

perl -ne 'BEGIN {read ARGV, "", 42-1}; …'

If you want portability, a lot of text processing tasks can be done in awk, but awk doesn't have backreferences at all, so extracting text from a string can be clumsy.

share|improve this answer
the -n was what I was looking for, as it makes this work like grep :) the use of $ARGV[0] was so that this could be called from within a script in a concise way (avoiding the extra '"$var'" escapes). It seems the -n flag will break ARGV from within a pipe so escapes will have to do! –  jorb Apr 19 '12 at 23:38

Your Answer


