Ваша sed
команда (с правильным цитированием):
sed 's/str1/str2/g'
Это изменит все вхождения str1
на str2
. Список файлов, содержащих str1
, можно получить из grep -l 'str1'
:
.
find. -type f \( -name '*.txt' -o -name '*.git' \) \
-exec grep -l 'str1' {} \; \
-exec sed -i 's/str1/str2/g' {} + >changelist.txt
Здесь grep -l
предоставит список имен путей, которые будут перенаправлены в changelist.txt
. Он также будет действовать как фильтр для sed
, так что sed
будет запускаться только для файлов, содержащих шаблон.Затем sed -i
внесет изменения в файлы (и будет молчать ).
В качестве альтернативы пусть find
напечатает пути к файлам, которые содержат строку:
find. -type f \( -name '*.txt' -o -name '*.git' \) \
-exec grep -q 'str1' {} \; \
-print \
-exec sed -i 's/str1/str2/g' {} + >changelist.txt
Похожие:
Во-первых, я предполагаю, что вы хотите, чтобы вывод grep направлялся в stderr? 2>&1 перенаправляет stderr на stdout. Вероятно, вам нужен grep 1>&2.
Во-вторых, перенаправление будет применяться только к этой единственной команде. Он не сохраняется, поэтому запуск и остановка перенаправления не проблема.
В-третьих, я не получаю :"успех" (systemd завершается нормально ). Все, что вы проверяете, это то, что вывод df -h упоминает /mnt/Backups. Что-то другое может нарушить процесс.
В-четвертых, состояние процессов в конвейерах иногда бывает неожиданным. Статус каждого процесса записывается в массив PIPESTATUS. Состояние газопровода в целом сложное. В частности, конвейер с перенаправлением может выполняться в подоболочке (, поэтому основная оболочка сохраняет свои потоки без изменений ). В таком случае я готов поверить, что ваш УСПЕХ связан со статусом выхода самой подоболочки, а не с последней командой в конвейере.
Я не уверен в этом, потому что не доверяю ему настолько, чтобы использовать его сам. Я бы хотел проверить текст, а не статус, например:(непроверенный):
MOUNT="$( df -h | grep --color=never /mnt/Backups )"
echo 1>&2 "Mount test gets ${MOUNT:-Nothing}"
if [[ "${MOUNT}" = "/mnt/Backups" ]]; then...
Этот материал очень трудно диагностировать. Я учусь использовать RC=$?
для сохранения статуса команды, echo $?
для отображения статуса команды, declare -p PIPESTATUS
для отображения массива статусов и RP="$( declare -p PIPESTATUS )"
для сохранения массива статусов.
Проблема в том, что все четыре из этих (, включая присвоения переменной ), также являются командами и приводят к сбросу статуса на ноль. Таким образом, вы никогда не сможете увидеть свой начальный статус команды более чем по одному маршруту. Статус эфемерен, данные навсегда.
Мой лучший механизм — заставить grep подсчитывать совпадения с grep -c
и сохранять возвращенное количество в переменной. Вам не нужно отбрасывать имя файла, потому что если grep читает стандартный ввод, он не выводит имя.
В качестве уточнения для больших файлов используйте grep -l
.Это завершается, когда он видит, что первое совпадение(grep -c
должно продолжать считать до конца ). grep -l
выводит имя файла, содержащего совпадение, поэтому тест выполняется для ""
или "(standard input)"
.