Найти сценарий оболочки и переименовать строку

#bash #shell #sed #find

#bash #оболочка #sed #Найти

Вопрос:

У меня есть сценарий оболочки с именем script.sh . Мне нужно найти этот скрипт и изменить значение внутри скрипта

От:

 bash $current_dir/run.sh
  

Для

 ./run.sh.x
  

мое решение выглядит примерно так:

 find -maxdepth 10 -name "script.sh" -exec sed -i 's#bash '$current_dir'#run.sh#.#runs.sh.x#' {}  ;
  

Но все равно моя команда не работает. Есть идеи, как заменить эту строку на новую строку в моем сценарии оболочки?

Ответ №1:

sed Похоже, проблема в вашем выражении.

Вы можете использовать:

 find . -maxdepth 10 -name "script.sh" -exec sed -i 's#bash $current_dir/run.sh#./run.sh.x#' {}  
  

Комментарии:

1. Спасибо за очень быстрый ответ. У меня ошибка — sed: не удается прочитать s #bash $current_dir/run.sh#./run.sh.x #: нет такого файла или каталога:-(

2. @Paul, если у вас есть GNU sed, удалите '' — похоже, это было написано правильно для macOS / BSD sed.

3. @Paul, … -i аргумент to sed не стандартизирован по POSIX, поэтому разные реализации обрабатывают его по-разному; одно из этих различий — то, что нас здесь зацепило.

4. @CharlesDuffy, да, спасибо за положительный комментарий. Я только что удалил кавычки ‘ ‘ и сейчас мне кажется, что все в порядке. Еще раз спасибо вам обоим, ребята.

5. @Paul: Действительно, Чарльз был прав, он был протестирован на OSX. Я удалил лишнее '' из sed команды.

Ответ №2:

@anubhava правильно. Еще одна команда sed, которую вы можете использовать.

 find . -maxdepth 10 -name "script.sh" -type f | xargs -I {} sed -i 's/.*/run.sh/./run.sh.x/g' {}
  

Комментарии:

1. @CharlesDuffy Спасибо за ваш вклад. Я поместил файл внутри каталога, который содержит пробелы, и он все еще работает и работает хорошо. AFAIK, -I также сможет обрабатывать пробелы.

2. На самом деле, вы правы. Каталоги с буквенными символами новой строки по-прежнему являются проблемой, но поведение с -I {} пробелами не является неправильным.

3. Тем не менее, чтобы продемонстрировать ошибку при использовании xargs without -0 с новыми строками в именах файлов: mkdir -p $'dirnwithnnewlines' amp;amp; touch $'dirnwithnnewlines/script.sh'; find . -name script.sh | xargs -I {} printf '<%s>n' {} ; вывод <dir> , <with> , <newlines/script.sh> .

4. …по сравнению с правильным поведением: mkdir -p $'dirnwithnnewlines' amp;amp; touch $'dirnwithnnewlines/script.sh'; find . -name script.sh -exec printf '<%s>n' {} ; в этом случае вывод (правильно) <dir , with , newlines/script.sh> .

5. Я не отрицаю, что это работает в обычном случае, я только указываю на то, что он вводит некоторые дополнительные ошибки (даже если они встречаются только при очень необычных обстоятельствах), когда можно было бы написать код, в котором их нет. Странные угловые случаи — это ошибки безопасности — подумайте о том, что кто-то создает вредоносный файл mkdir -p $'./tmp/n/etc/passwdn' amp;amp; touch $'./tmpn/etc/passwdn/script.sh , обманывая ваш код для изменения /etc/passwd .

Ответ №3:

Один из способов обойти sed проблемы совместимости — полагаться на perl . Принятие ответа от BashFAQ #21:

 search='bash $current_dir/run.sh'
replace='./run.sh.x'
in="$search" out="$replace" find . -name script.sh -exec 
  perl -pi -e 's/Q$ENV{"in"}/$ENV{"out"}/g' '{}'