Ответы:
OS X использует сочетание инструментов BSD и GNU, поэтому лучше всегда проверять документацию (хотя у меня она less
даже не соответствовала справочной странице OS X):
sed принимает аргумент после -i
как расширение для резервных копий. Если -i ''
нет резервных копий, укажите пустую строку ( ).
Следующее должно сделать:
LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
Это -type f
просто хорошая практика; sed будет жаловаться, если вы дадите ему каталог или около того.
-exec
предпочтительнее xargs
; вам не нужно беспокоиться -print0
ни о чем. Значок {} +
в конце означает, что find
все результаты будут добавлены в качестве аргументов к одному экземпляру вызываемой команды, вместо того, чтобы повторно запускать ее для каждого результата. (Одно исключение - когда максимальное количество аргументов командной строки, разрешенное ОС, нарушено; в этом случае find
будет запущено более одного экземпляра.)
%
символ: sed "s%localhost/site%blah/blah%"
. Другой альтернативой является обратной косой черты избежать разделитель: sed "s/localhost\/site/blah\/blah/"
.
illegal byte sequence
ошибку? если да, попробуйте: LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
у меня сработало.
/g
для нескольких валют, напримерLC_ALL=C find . -type f -exec sed -i '' s/search/replace/g {} +
Для Mac более похожий подход будет следующим:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
find . -name '*.php' -print0 | xargs -0 sed -i "" "s/easyform/form360/g"
В качестве альтернативного решения я использую это на Mac OSX 10.7.5.
grep -ilr 'old-word' * | xargs -I@ sed -i '' 's/old-word/new-word/g' @
Кредит принадлежит: ответ Тодда Сезера
Ничего из вышеперечисленного не работает на OSX.
Сделайте следующее:
perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
Версия, которая работает как в Linux, так и в Mac OS X (путем добавления -e
переключателя в sed
):
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
export LC_CTYPE=C && export LANG=C
Всякий раз, когда я набираю эту команду, мне всегда кажется, что я ее пропускаю или забываю флаг. Я создал Gist на github на основе ответа TaylanUB, который выполняет глобальную замену поиска из текущего каталога. Это специфично для Mac OSX.
https://gist.github.com/nateflink/9056302
Это приятно, потому что теперь я просто открываю терминал и копирую:
curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
Вы можете получить некоторые странные ошибки последовательности байтов, поэтому вот полный код:
#!/bin/bash
#By Nate Flink
#Invoke on the terminal like this
#curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: ./$0 [find string] [replace string]"
exit 1
fi
FIND=$1
REPLACE=$2
#needed for byte sequence error in ascii to utf conversion on OSX
export LC_CTYPE=C;
export LANG=C;
#sed -i "" is needed by the osx version of sed (instead of sed -i)
find . -type f -exec sed -i "" "s|${FIND}|${REPLACE}|g" {} +
exit 0
Я использовал этот формат - но ... Я обнаружил, что мне нужно запускать его три или более раз, чтобы заставить его фактически изменить каждый экземпляр, который я нашел чрезвычайно странным. При однократном запуске некоторые из них будут изменены в каждом файле, но не все. Выполнение одной и той же строки два-четыре раза приведет к перехвату всех экземпляров.
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +
g
, потому что вашему регулярному выражению sed нужен a в конце, иначе он заменяет только первое вхождение thistext
в строке. Итак, ваше регулярное выражение должно бытьs/thistext/newtext/g
https://bitbucket.org/masonicboom/serp - это утилита go (то есть кроссплатформенная), протестированная на OSX, которая выполняет рекурсивный поиск и замену текста в файлах в заданном каталоге и подтверждает каждую замену. Он новый, так что может глючить.
Использование выглядит так:
$ ls test
a d d2 z
$ cat test/z
hi
$ ./serp --root test --search hi --replace bye --pattern "*"
test/z: replace hi with bye? (y/[n]) y
$ cat test/z
bye
find . -type f | xargs sed -i '' 's/string1/string2/g'
Обратитесь сюда для получения дополнительной информации.
Команда в OSX должна быть точно такой же, как и в Unix с красивым пользовательским интерфейсом.
-print0
добавлены в find
флагах и -0
на xargs
флагах.
-exec sed -i s/this/that/g {} \+
вместо -print
и xargs
xargs
может отображаться разделенный пробелами «./jacobus» как файл для перехода sed
, а затем с «R.txt» , ни один из которых не существует.
можно просто сказать $ PWD вместо "."
apple.stackexchange.com
поскольку он недостаточно универсален для Linux и всех разработчиков.