команда Sed в сухом беге - PullRequest
       4

команда Sed в сухом беге

38 голосов
/ 22 декабря 2010

Я не могу выяснить, можно ли и как сделать пробный прогон с помощью sed.

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

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

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

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

Ответы [ 3 ]

30 голосов
/ 22 декабря 2010

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

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

while IFS= read -r -d $'\0' file; do
  sed -i 's/string1/string2/g' "$file"
done < <(find ./ -type f -print0)
14 голосов
/ 23 июня 2015

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

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

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

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

От man sed:

p:

Печать текущего пространства шаблона.

- quiet:

подавление автоматической печати шаблонапробел

6 голосов
/ 12 мая 2016

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

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

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-pacesed, вы можете сделать разность снова с некоторыми информативными сообщениями:

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
...