Подтвердить что ты не робот

Как запустить команду sed с помощью ввода и вывода в виде одного и того же файла?

Я пытаюсь использовать команду sed в оболочке script, где я хочу удалить строки, которые читают STARTremoveThisComment, и строки, которые читают removeThisCommentEND.

Я могу сделать это, когда я скопирую его в новый файл, используя

sed 's/STARTremoveThisComment//' > test

Но как это сделать, используя тот же файл, что и вход и выход?

4b9b3361

Ответ 1

sed -i (или расширенная версия, --in-place) автоматизирует процесс, обычно выполняемый с использованием менее продвинутых реализаций, который отправляет вывод во временный файл, а затем переименовывает его обратно в оригинал.

-i предназначен для редактирования на месте, и вы также можете предоставить суффикс резервного копирования для хранения копии оригинала:

sed -i.bak fileToChange
sed --in-place=.bak fileToChange

Оба из них сохранят исходный файл в fileToChange.bak.

Имейте в виду, что редактирование на месте не может быть доступно во всех реализациях sed, но оно находится в GNU sed, которое должно быть доступно для всех вариантов Linux в соответствии с вашими тегами.

Если вы используете более примитивную реализацию, вы можете использовать что-то вроде:

sed 'whatever' oldfile >newfile ; mv newfile oldfile

хотя некоторые проверки ошибок были бы приятными.

Ответ 2

Вы можете использовать флаг -i для редактирования на месте и -e для указания обычного выражения script:

sed -i -e 's/pattern_to_search/text_to_replace/' file.txt

Чтобы удалить строки, соответствующие определенному шаблону, вы можете использовать более простой синтаксис. Обратите внимание на флаг d:

sed -i '/pattern_to_search/d' file.txt

Ответ 3

Вы действительно не должны использовать sed для этого. Этот вопрос, кажется, возникает довольно часто, и это кажется очень странным, так как общее решение настолько тривиально, что кажется странным, что люди хотят знать, как это сделать в sed, и в python, и в ruby, и т.д. Если вы хотите, чтобы фильтр работал на входе и перезаписывал его, используйте следующий простой script:

#!/bin/sh -e
in=${1?No input file specified}
mv $in ${bak=.$in.bak}
shift
"[email protected]" < $bak > $in

Поместите это в свой путь в имя исполняемого файла inline, а затем проблема будет решена в целом. Например:

inline input-file sed -e s/foo/bar/g

Теперь, если вы хотите добавить логику для сохранения нескольких резервных копий или если у вас есть некоторые опции для изменения схемы именования резервных копий или что-то еще, вы можете исправить ее в одном месте. Какая опция командной строки получает 1-up счетчики в файле резервной копии при обработке файла на месте с помощью perl? Как насчет ruby? Опция отличается от gnu-sed? Как awk справится с этим? Целая точка unix - это то, что инструменты делают только одно. Обработка логики для файлов резервных копий - это вторая вещь, и ее необходимо учесть. Если вы реализуете инструмент, не добавляйте логику для создания файлов резервных копий. Попросите пользователей использовать для этого 2-й инструмент. Интеграция плохая. Модульность хорошая. Это путь unix.

Обратите внимание, что этот script имеет несколько проблем. Например, разрешения/режим входного файла могут быть изменены. Я уверен, что есть и другие проблемы. Однако, поместив логику резервного копирования в оболочку script, вы локализуете все эти проблемы и не должны беспокоиться о том, что sed перезаписывает файлы и режим изменений, а python сохраняет файл на месте и не выполняет измените индексный дескриптор (я составил эти два случая, в том случае, если не все инструменты будут использовать одну и ту же логику, а оболочка script будет.)

Ответ 4

Насколько я знаю, невозможно использовать один и тот же файл для ввода и вывода. Хотя одно из решений делает оболочку script, которая сохранит ее в другом файле, удалит старый вход и переименует вывод в имя входного файла.

sed -e s/try/this/g input.file > output.file;mv output.file input.file

Ответ 5

Я предлагаю использовать sponge

Губка читает стандартный ввод и записывает его в указанный файл. В отличие от перенаправления оболочки, губка впитывает весь свой ввод перед записью выходного файла. Это позволяет создавать конвейеры, которые читают и пишут в один и тот же файл.

cat test | sed 's/STARTremoveThisComment//' | sponge test