Редактирование на месте с помощью sed в OS X
Я хотел бы отредактировать файл с помощью sed в OS X. Я использую следующую команду:
sed 's/oldword/newword/' file.txt
Выход отправляется на терминал. file.txt не изменяется. Изменения сохраняются в file2.txt с помощью этой команды:
sed 's/oldword/newword/' file1.txt > file2.txt
Однако я не хочу другой файл. Я просто хочу отредактировать file1.txt. Как я могу это сделать?
Я пробовал флаг -i. Это приводит к следующей ошибке:
sed: 1: "file1.txt": invalid command code f
8 ответов
Вы можете правильно использовать флаг -i, предоставив ему суффикс для добавления в файл резервной копии. Расширяем ваш пример:
sed -i.bu 's/oldword/newword/' file1.txt
Вам дадут два файла: один с именем file1.txt, который содержит подстановку, а другой с именем file1.txt.bu, который имеет исходное содержимое.
Мягко опасный
Если вы хотите деструктивно перезаписать исходный файл, используйте что-то вроде:
sed -i '' 's/oldword/newword/' file1.txt
^ note the space
Из-за способа анализа строки между флагом параметра и его аргументом требуется пробел, поскольку аргумент имеет нулевую длину.
Помимо возможной поломки вашего оригинала, я не знаю никаких дальнейших опасностей обмана сэд таким образом. Следует отметить, однако, что если этот вызов sed
является частью сценария, Unix Way™ (IMHO) будет использовать sed
неразрушающе, проверьте, что он вышел чисто, и только затем удалите посторонний файл.
The
-i
флаг, вероятно, не работает для вас, потому что вы следовали примеру GNU sed , в то время как macOS использует BSD sed , и у них немного другой синтаксис.
Все остальные ответы говорят вам, как исправить синтаксис для работы с BSD sed. Альтернативой является установка GNU sed на macOS с помощью:
brew install gsed
а затем использовать его вместо
sed
версия, поставляемая с macOS (обратите внимание на
g
префикс), например:
gsed -i 's/oldword/newword/' file1.txt
Если вы хотите, чтобы команды GNU sed всегда были переносимы на вашу macOS, вы можете добавить каталог «gnubin» к своему пути, добавив что-то вроде этого в свой
.bashrc
/
.zshrc
файл (выполнить
brew info gsed
чтобы увидеть, что именно вам нужно сделать):
export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
и с этого момента GNU sed становится вашим sed по умолчанию, и вы можете просто запустить:
sed -i 's/oldword/newword/' file1.txt
У меня похожая проблема с MacOS
sed -i '' 's/oldword/newword/' file1.txt
не работает, но
sed -i"any_symbol" 's/oldword/newword/' file1.txt
работает хорошо.
Ты можешь использовать -i''
(--in-place
) за sed
как уже предлагалось. Смотрите: -i
аргумент на месте, однако обратите внимание, что -i
опция нестандартных расширений FreeBSD и может быть недоступна в других операционных системах. во-вторых sed
является редактором S Tream ED, а не редактором файлов.
Альтернативный способ - использовать встроенную замену в режиме Vim Ex, например:
$ ex +%s/foo/bar/g -scwq file.txt
и для нескольких файлов:
$ ex +'bufdo!%s/foo/bar/g' -scxa *.*
Для рекурсивного редактирования всех файлов вы можете использовать **/*.*
если оболочка поддерживает это (включить shopt -s globstar
).
Другой способ заключается в использовании gawk
и его новое расширение "на месте", такое как:
$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1
Это создает файлы резервных копий. Например sed -i -e 's/hello/hello world/' testfile
для меня создает файл резервной копии, testfile-e, в том же каталоге.
Ты можешь использовать,
sed -i -e 's ///'
Например, sed -i -e 's/Hello/Bye/' file.txt
это работает безупречно в Mac
Если вам нужно заменить более одного слова:
sed -i '' -e 's/_tools/tools/' -e 's/_static/static/' test.txt