1

I have a Linux folder tree with mixed shell, Perl and Python scripts. None of the scripts have consistent file extensions (.pl, .perl, .py, .sh, or no extension at all). I need to identify which files are Perl scripts, then add a new line of code to set a variable if the variable is not already in the Perl script.

Thanks to How to insert newline character after comma in `),(` with sed? I came up with this code that uses sed to insert the new line of code.

This code works, but is there a more efficient way to do it?

#! /bin/bash

NL='
$|++'

for f in `find "$1" -type f`
do
    if [ $(grep -cP "^\#\!/.+/perl" "${f}") -gt 0 ]
    then
        if [ $(grep -c "$|" "${f}") -eq 0 ]
        then
            sed -i -r "s/^#!\/(.+)\/perl(.+)$/#!\/\1\/perl\2\\${NL}/g" "${f}"
        fi
    fi
done
Community
  • 1
  • 1
tahoar
  • 1,788
  • 3
  • 20
  • 36

2 Answers2

1

You have a number of Useless Uses of Grep -c there. See http://porkmail.org/era/unix/award.html

#! /bin/bash

NL='
$|++'

for f in `find "$1" -type f`
do
    grep -qP "^\#\!/.+/perl" "${f}" &&
    ! grep -q "$|" "${f}" &&
    sed -i -r "s/^#!\/(.+)\/perl(.+)$/#!\/\1\/perl\2\\${NL}/g" "${f}"
done

The short-circuit && is not an optimization, just a personal preference. You could just as well keep your nested ifs, or perhaps something like

    if grep -qP "^#!/.+/perl" "$f" && ! grep -q "$|" "$f"; then ...

It might be more efficient still to do the first grep (at least) in a sed script since presumably you are only interested in the first line of the script. (On the other hand, why do you have a /g flag on the sed substitution if that is the case?)

Actually you probably mean

    sed -i -r "1s%^(#!/.+/perl.*)$%\1\\${NL}%" "$f"
slm
  • 15,396
  • 12
  • 109
  • 124
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thank you Tripleee. This is much faster because grep doesn't search the whole file with -q. Why did I have the /g? Because I didn't know what I was doing :) Yes, I used your suggested alternative. Please note your substitution adds an extra "#!/" because it was captured in the group. I removed it. Thanks again. – tahoar May 10 '12 at 10:42
  • Oops; fixed. Thanks for noticing. – tripleee May 10 '12 at 15:59
0

You could also use the file(1) command:

$ head -n 1 perl_script_wo_ext
#!/usr/bin/perl
$ file perl_script_wo_ext
perl_script_wo_ext: Perl script, ASCII text executable

Then grep for \bPerl script\b in that and you're set.

Boldewyn
  • 81,211
  • 44
  • 156
  • 212