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?


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.

  • 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

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.