Подтвердить что ты не робот

Команда sed в сухом пробеге

Я не могу узнать, как и как можно сделать сухой пробег с sed.

Итак, у меня есть эта команда:

find ./ -type f | xargs sed -i 's/string1/string2/g'

Но прежде чем я действительно заменим все файлы, я хочу проверить, что это заменит. Копирование всей структуры каталогов для проверки не является параметром!

Спасибо за любую обратную связь (отрицательную или положительную:))

4b9b3361

Ответ 1

Удалите -i и проведите его до less, чтобы разбивать страницы на результаты. Кроме того, вы можете перенаправить все это на один большой файл, удалив -i и добавляя > dryrun.out

Я должен отметить, что этот script из вас будет терпеть неудачу с файлами, которые содержат пробелы в их имени или других гнусных персонажах, таких как новые строки или многое другое. Лучший способ сделать это:

while IFS= read -r -d $'\0' file; do
  sed -i 's/string1/string2/g' "$file"
done < <(find ./ -type f -print0)

Ответ 2

Я бы предпочел использовать p-опцию:

find ./ -type f | xargs sed 's/string1/string2/gp'

Может быть объединен с параметром --quiet для менее подробного вывода:

find ./ -type f | xargs sed --quiet 's/string1/string2/gp'

От man sed:

р

Распечатайте текущее пространство шаблонов.

- тихо:

подавляет автоматическую печать пространства шаблонов

Ответ 3

Я знаю, что это очень старый поток, и OP действительно не нуждается в этом ответе, но я пришел сюда в поисках режима сухого режима, поэтому подумал о добавлении ниже совета для любого, кто придет сюда в будущем. То, что я хотел сделать, это не топать файл резервной копии, если нет чего-то действительно меняющегося. Если вы слепо запускаете sed, используя опцию -i с суффиксом резервного копирования, существующий файл резервной копии перезаписывается, даже если ничего не заменено.

То, как я закончил это, - это подключить вывод sed к diff и посмотреть, не изменилось ли что-то, а затем перезапустить с обновлением на месте, что-то вроде этого:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    sed -i.bak -e 's/string1/string2/g' $fpath
fi

В соответствии с вопросом OP, если требование состоит в том, чтобы просто увидеть, что изменилось бы, вместо того, чтобы запускать in-pace sed, вы могли бы снова выполнить diff с некоторыми информативными сообщениями:

if ! sed -e 's/string1/string2/g' $fpath | diff -q $fpath - > /dev/null 2>&1; then
    echo "File $fpath will change with the below diff:"
    sed -e 's/string1/string2/g' $fpath | diff $fpath -
fi

Вы также можете захватить вывод в переменной, чтобы избежать его дважды:

diff=$(sed -e 's/string1/string2/g' $fpath | diff $fpath -)
if [[ $? -ne 0 ]]; then
    echo "File $fpath will change with the below diff:"
    echo "$diff"
fi