Как вставить новую строку кода только в Perl-скрипты с помощью Bash-скрипта

У меня есть дерево папок Linux со смешанной оболочкой, сценариями Perl и Python. Ни один из сценариев не имеет согласованных расширений файлов (.pl, .perl, .py, .sh или вообще не имеет расширения). Мне нужно определить, какие файлы являются сценариями Perl, а затем добавить новую строку кода для установки переменной, если этой переменной еще нет в сценарии Perl.

Благодаря Как вставить символ новой строки после запятой в `) ,(` с sed? Я придумал этот код, который использует sed для вставки новой строки кода.

Этот код работает, но есть ли более эффективный способ сделать это?

#! /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

person tahoar    schedule 10.05.2012    source источник


Ответы (2)


У вас есть ряд бесполезных применений Grep -c. См. 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

Короткое замыкание && — это не оптимизация, а просто личное предпочтение. С тем же успехом вы могли бы сохранить свои вложенные if или что-то вроде

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

Возможно, было бы более эффективно выполнить первый grep (по крайней мере) в сценарии sed, поскольку, по-видимому, вас интересует только первая строка сценария. (С другой стороны, почему у вас есть флаг /g для замены sed, если это так?)

На самом деле вы, вероятно, имеете в виду

    sed -i -r "1s%^(#!/.+/perl.*)$%\1\\${NL}%" "$f"
person tripleee    schedule 10.05.2012
comment
Спасибо Трипли. Это намного быстрее, потому что grep не ищет весь файл с -q. Почему у меня есть / g? Потому что я не знал, что делаю :) Да, я использовал предложенную вами альтернативу. Обратите внимание, что ваша замена добавляет дополнительный #!/, потому что он был захвачен в группе. Я удалил его. Спасибо еще раз. - person tahoar; 10.05.2012
comment
Ой; исправлено. Спасибо, что заметили. - person tripleee; 10.05.2012

Вы также можете использовать команду file(1):

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

Затем grep для \bPerl script\b в этом, и все готово.

person Boldewyn    schedule 10.05.2012