#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
аргумент tosed
не стандартизирован по 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' '{}'