полезный ответ Мартина Клейтона дает хорошее объяснение проблемы [1] , но решение, которое, как он заявляет, имеет потенциально нежелательный побочный эффект.
Вот решения без побочных эффектов :
Предостережение : решения одной только синтаксической проблемы -i
, как показано ниже, может быть недостаточно, поскольку существует много других отличий между GNU sed
и BSD / macOS sed
(для всестороннего обсуждение, см. мой ответ мой).
Обходной путь с -i
: создайте файл резервной копии временно , затем очистите его:
С опциональным аргументом непустой суффикс (расширение имени файла резервной копии) (значение не пустая строка ), вы можете используйте -i
таким образом, чтобы он работал как с BSD / macOS sed
, так и с GNU sed
, путем , напрямую добавляя суффикс к опции -i
.
Это можно использовать для временного создания файла резервной копии , который вы можете сразу очистить:
sed -i.bak 's/foo/bar/' file && rm file.bak
Очевидно, что если вы хотите сохранить резервную копию, просто пропустите часть && rm file.bak
.
Обходной путь, совместимый с POSIX, с использованием временного файла и mv
:
Если на месте редактируется только один файл , параметр -i
может быть обойден , чтобы избежать несовместимости.
Если вы ограничите свой sed
сценарий и другие опции POSIX-совместимыми функциями , ниже будет полностью переносимое решение (обратите внимание, что -i
является не POSIX-совместимый ).
sed 's/foo/bar' file > /tmp/file.$$ && mv /tmp/file.$$ file
Эта команда просто записывает изменения во временный файл и, если команда sed
завершается успешно (&&
), заменяет исходный файл временным.
- Если вы хотите сохранить исходный файл в качестве резервной копии, добавьте еще одну команду
mv
, которая сначала переименует исходный файл.
Предупреждение : По сути, это то же самое, что делает -i
, за исключением того, что он пытается сохранить разрешения и расширенные атрибуты (macOS) исходного файла; однако, если исходный файл представляет собой символьную ссылку , и это решение, и -i
заменят символическую ссылку на обычный файл .
См. Нижнюю половину моего ответа моего для деталей о том, как -i
работает.
[1] Более подробное объяснение см. этого ответа моего.