Невозможно использовать SED для быстрого редактирования файлов - PullRequest
3 голосов
/ 06 апреля 2009

Файл изначально

$cat so/app.yaml 
application: SO
...

Я запускаю следующую команду. Я получаю пустой файл.

$sed s/SO/so/ so/app.yaml > so/app.yaml 
$cat so/app.yaml 
$

Как вы можете использовать SED для редактирования файла, не давая мне пустой файл?

Ответы [ 4 ]

16 голосов
/ 06 апреля 2009
$ sed -i -e's/SO/so/' so/app.yaml

-i означает на месте.

5 голосов
/ 06 апреля 2009

Вы используете не тот инструмент для работы. sed - это редактор stream (поэтому он называется s ed), поэтому он предназначен для редактирования потоков в трубе в полете. ed OTOH - это файл редактор, который может делать все, что может sed, за исключением того, что он работает с файлами вместо потоков. (На самом деле все наоборот: ed - оригинальная утилита, а sed - клон, который избегает необходимости создавать временные файлы для потоков.)

ed работает очень похоже на sed (потому что sed - это просто клон), но с одним важным отличием: вы можете перемещаться в файлах, но не можете перемещаться в потоках. Таким образом, все команды в ed принимают параметр адреса, который сообщает ed, , где в файле, чтобы применить команду. В вашем случае вы хотите применить команду везде в файле, поэтому параметр адреса просто ,, потому что a,b означает «от строки a до строки b» и значение по умолчанию для a - 1 (начало файла), а по умолчанию для b - $ (конец файла), поэтому оставить их обоих означает «от начала файла до конца- из файла». Затем идет s (для замены), а остальное выглядит очень похоже на sed.

Итак, ваша sed команда s/SO/so/ превращается в команду ed ,s/SO/so/.

И, опять же, поскольку ed является файловым редактором, а точнее интерактивным файловым редактором, нам также нужно написать (w) файл и выйти из (q) редактора.

Вот как это выглядит в целом:

ed -- so/app.yaml <<-HERE
    ,s/SO/so/
    w
    q
HERE

См. Также мой ответ на аналогичный вопрос.

Что происходит в вашем случае, так это то, что выполнение конвейера является двухэтапным процессом: сначала создайте конвейер, затем запустите его. > означает «открыть файл, обрезать его и подключить к файловому дескриптору 1 (stdout)». Только тогда канал фактически запускается, то есть выполняется sed, но на данный момент файл уже обрезан.

В некоторых версиях sed также есть параметр -i для редактирования файлов на месте, что делает sed немного более похожим на ed, но использовать его не рекомендуется: во-первых, это не поддерживает все функции ed, но, что более важно, это нестандартизированное проприетарное расширение GNU sed, которое не работает во многих не-GNU системах. Прошло много времени с тех пор, как я использовал систему без GNU, но в последний раз я использовал ее, ни Solaris, ни OpenBSD, ни HP-UX, ни IBM AIX sed не поддерживали параметр -i.

5 голосов
/ 06 апреля 2009

>, используемый в трубопроводе, откроет выходной файл, когда все каналы будут установлены, т.е. перед выполнением команды. Таким образом, входной файл усекается до выполнения sed. Это проблема со всеми перенаправлениями оболочки, а не только с sed.

Ответ Шелдона Янга показывает, как использовать редактирование на месте.

3 голосов
/ 06 апреля 2009

Я считаю, что перенаправление вывода в тот же файл, который вы редактируете, вызывает вашу проблему.

Вам нужно перенаправить стандартный вывод в какой-то временный файл, и когда команда sed выполнит перезапись исходного файла временным.

...