find + sed добавляет строку в начало файла, только если ее там нет - PullRequest
0 голосов
/ 29 декабря 2018

Я пишу скрипт, который добавляет строку в начало файлов в каталоге.Следующий код ниже делает это.

 find . -type d \(  -name ThirdParty  -o  -name 3rdParty -o \
                    -name 3rd_party \) \
        -prune -o -type f \( -name "*.java"  -o -name "*.cs"    -o \
                             -name "*.cpp"   -o -name "*.cxx"   -o \
                             -name "*.cc"    -o -name "*.c"     -o \
                             -name "*.h"     -o -name "*.scala" -o \
                             -name "*.css"   -o -name "*.js" \) \
      -print0 | 
xargs -0 sed -i  '1s/^/\/*RIGHTS AND ETC ETC ETC/*'

Однако я хочу добавить эту строку ТОЛЬКО, если ее еще нет в файле.Я пытался использовать grep и трубопровод до использования sed как так:

grep -q "/*RIGHTS AND ETC ETC ETC/*" | sed -i....

, но когда я запускаю скрипт, я получаю sed: no input files.Я просто запускаю этот скрипт в каталоге, поэтому нет входных файлов.Спасибо.

Ответы [ 3 ]

0 голосов
/ 29 декабря 2018

grep не требуется.sed может выполнить отрицательный поиск и сделать условное выражение i nsert :

... -print0 | xargs -0 sed -i '1{/^\/\*RIGHTS AND ETC ETC ETC\*\/$/!i\
/\*RIGHTS AND ETC ETC ETC\*/
}'

Примечания:

  • перевод строки в трех строках кода необходим для правильной работы i.

  • неясно, являются ли * буквальными или нет, поэтому они цитируются так: \*.

0 голосов
/ 29 декабря 2018

Это может сработать для вас (GNU sed и find):

(var="/*RIGHTS AND ETC ETC ETC/*" ;
find whatever  \! -exec grep -qF "$var" {} \; -exec sed -i '1i\'"$var" {} \;)

Где whatever - начальные команды поиска.

Это будет только вставить переменную var, еслиgrep не нашел var нигде в каждом файле.

0 голосов
/ 29 декабря 2018

Ваша команда grep ничего не печатает, потому что вы использовали опцию -q;он просто устанавливает состояние выхода в зависимости от того, соответствует ли файл.

Вы хотите напечатать все имена файлов, которые не соответствуют, поэтому вы можете передать эти имена в sed.Вы можете сделать это с помощью опции -L вместе с -z, чтобы использовать нулевой терминатор вместо новой строки (например, опция -print0 в find).

Вам также следует использовать -Fобрабатывать строку как фиксированную строку, а не как шаблон регулярного выражения.

find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) -prune \
    -o -type f \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.js" \) -print0 |
xargs -0 grep -Lz -F "/*RIGHTS AND ETC ETC ETC/*" |
xargs -0 sed -i ...
...