Рекурсивный поиск и замена в текстовых файлах на Mac и Linux
В оболочке linux следующая команда будет рекурсивно искать и заменять все экземпляры 'this' на "это" (у меня нет оболочки Linux передо мной, но она должна делать).
find . -name "*.txt" -print | xargs sed -i 's/this/that/g'
Как будет выглядеть аналогичная команда в OSX?
Ответы
Ответ 1
OS X использует сочетание инструментов BSD и GNU, поэтому лучше всегда проверять документацию (хотя у меня было такое, что даже less
не соответствовало man-странице OS X):
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html
Sed принимает аргумент после -i
как расширение для резервных копий. Укажите пустую строку (-i ''
), чтобы не было резервных копий.
Следующее должно сделать:
LC_ALL=C find. -type f -name '*.txt' -exec sed -i '' s/this/that/{} +
-type f
- просто хорошая практика; Сед будет жаловаться, если вы дадите ему каталог или около того. -exec
предпочтительнее xargs
; вам не нужно беспокоиться о -print0
или о чем-то еще. {} +
В конце означает, что команда find
будет добавлять все результаты в качестве аргументов к одному экземпляру вызываемой команды вместо повторного запуска для каждого результата. (Единственное исключение - это когда максимальное количество аргументов командной строки, разрешенных ОС, нарушается; в этом случае find
запускает более одного экземпляра.)
Ответ 2
Для mac, более похожий подход будет таким:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
Ответ 3
Как альтернативное решение, я использую этот вариант на Mac OSX 10.7.5
grep -ilr 'old-word' * | xargs [email protected] sed -i '' 's/old-word/new-word/g' @
Кредит идет: Ответ Тодда Цезер
Ответ 4
В Mac OSX 10.11.5 это отлично работает:
grep -rli 'old-word' * | xargs [email protected] sed -i '' 's/old-word/new-word/g' @
Ответ 5
Ничего из вышеперечисленного не работает в OSX.
Выполните следующие действия:
perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
Ответ 6
Версия, которая работает как на 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'
Ответ 7
Это моя работоспособная. на Mac OS X 10.10.4
grep -e 'this' -rl . | xargs sed -i '' 's/this/that/g'
Вышеупомянутые приложения find изменят файлы, которые не содержат текст поиска (добавьте новую строку в конец файла), который является подробным.
Ответ 8
Если вы используете zsh-терминал, вы можете использовать магию подстановочных знаков:
sed -i "" "s/search/high-replace/g" *.txt
Ответ 9
Всякий раз, когда я набираю эту команду, мне всегда кажется, что она ее подвешивает или забывает флаг. Я создал 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
Ответ 10
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
Ответ 11
find . -type f | xargs sed -i '' 's/string1/string2/g'
Обратитесь сюда для получения дополнительной информации.
Ответ 12
Я использовал этот формат - но... я обнаружил, что мне нужно было запустить его три или более раз, чтобы заставить его фактически изменять каждый экземпляр, что мне показалось очень странным. Запуск его один раз изменит некоторые в каждом файле, но не во всех. Выполнение одной и той же строки два-четыре раза перехватит все экземпляры.
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +
Ответ 13
Команда OSX должна быть точно такой же, как и Unix под симпатичным интерфейсом.
Ответ 14
может просто сказать $PWD вместо "."