Команда sed в сухом пробеге
Я не могу узнать, как и как можно сделать сухой пробег с sed.
Итак, у меня есть эта команда:
find ./ -type f | xargs sed -i 's/string1/string2/g'
Но прежде чем я действительно заменим все файлы, я хочу проверить, что это заменит. Копирование всей структуры каталогов для проверки не является параметром!
Спасибо за любую обратную связь (отрицательную или положительную:))
Ответы
Ответ 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