I want to print all .sh files in a directory. So I tried the following command -
ll | perl -pe 's/(.*)([0-9]*:[0-9]* *)(.*\.sh)/$3/'
The last match (.*sh)
is what I am interested in. The command works correctly for all those files that have the .sh extension. However, it also prints all the other files (the entire line i.e.) where the substitution was not possible.
Is there a way I can specify that perl should print the output only if substitution actually occurred?
If you use -n
instead of -p
, Perl will loop over the lines without automatically printing them out. Then you can add your own print
statement that's conditional on the success of the substitution:
ll | perl -ne 'print if s/(.*)([0-9]*:[0-9]* *)(.*\.sh)/$3/'
This is only a bit longer than the equivalent sed -ne 's/.../.../p'
, which is what I would use for simple cases that don't require more complicated logic beyond the substitution+print.
Also, those extra groups aren't doing anything in this example, so you could simplify to this:
ll | perl -ne 'print if s/^.*[0-9]:[0-9]*\s+(.*\.sh)$/$1/'
or, since you're doing the printing yourself instead of letting -p
do it for you, you can skip the substitution and leave $_
alone, while just printing out the part you want. That means you don't get the newline for free, though. Here I used -l
to compensate for that fact:
ll | perl -lne 'print $1 if /^.*[0-9]:[0-9]*\s+(.*\.sh)$/'
But you could also use the modern convenience operator say
:
ll | perl -nE 'say $1 if /^.*[0-9]:[0-9]*\s+(.*\.sh)$/'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With