Sed: -i не может использоваться с stdin в Mac OS X

Я использую в моем проекте парсер бизонов. Когда я запускаю следующую команду:

sed -i y.tab.c -e "s/  __attribute__ ((__unused__))$/# ifndef __cplusplus\n  __attribute__ ((__unused__));\n# endif/"

Я получаю эту ошибку sed: -i не может использоваться с stdin

Команда отлично работает в Linux-машинах. Я использую Mac OS X 10.9. Он выдает ошибку только на mac os x. Я не знаю, почему. Может ли кто-нибудь помочь?

Спасибо

Ответы

Ответ 1

Вам нужно поместить входной файл в качестве последнего параметра.

sed -i -e "s/  __attribute__ ((__unused__))$/# ifndef __cplusplus\n  __attribute__ ((__unused__));\n# endif/" y.tab.c

Ответ 2

Проблема заключается в том, что Mac OS X использует версию BSD sed, которая рассматривает вариант -i несколько иначе. Версия GNU, используемая в Linux, принимает необязательный аргумент с -i: если присутствует, sed создает файл резервной копии, имя которого состоит из входного файла плюс аргумент. Без аргумента sed просто изменяет входной файл без сохранения резервной копии оригинала.

В BSD sed требуется аргумент -i. Чтобы избежать создания резервной копии, вам необходимо указать аргумент нулевой длины, например. sed -i '' y.tab.c ....

Ваша команда, которая просто редактирует y.tab.c без резервного копирования в Linux, попытается сохранить файл резервной копии, используя 'y.tab.c' в качестве расширения. Но теперь, без другого файла в командной строке, sed считает, что вы хотите редактировать стандартный ввод на месте, что-то, что не разрешено.

Ответ 3

Из командной строки sed:

-i расширение    Редактируйте файлы на месте, сохраняя резервные копии с указанным расширением.    Если задано расширение с нулевой длиной, резервная копия не будет сохранена. Это    не рекомендуется указывать удлинитель нулевой длины, когда на месте    редактируя файлы, поскольку вы рискуете коррупцией или частичным контентом на месте,    где дисковое пространство исчерпано и т.д.

Решение состоит в том, чтобы отправить расширение нулевой длины следующим образом:

sed -i '' 's/apples/oranges/' file.txt

Ответ 4

Piggy - отключение объяснения @chepner для быстрого и грязного решения:

Установите версию sed, которая выполнит задание с помощью brew install gnu-sed, а затем заменит использование sed в script gsed.

(Сообщество homebrew довольно осведомлено о проблемах, которые могут возникнуть из встроенных модулей OS X, неожиданно переопределяется и сработало, чтобы не делать этого для большинства команд альтернативного дистрибутива.)