Использование here-doc для `sed` и файла

10

Я хочу использовать here-doc для команд sed и предоставить файл для чтения и выходной файл.

Я посмотрел руководство Here-Documents из Advanced Bash Scripting, но в нем ничего не говорится о регулярных аргументах при использовании here-doc. Это вообще возможно?

Я хотел бы добиться чего-то вроде следующего:

#!/bin/bash
OUT=/tmp/outfile.txt
IN=/my_in_file.txt

sed $IN << SED_SCRIPT
    s/a/1/g
    s/test/full/g

SED_SCRIPT 
> $OUT;

Любая помощь очень ценится.

Tristian
источник

Ответы:

14

Вы можете указать GNU sed читать сценарий из стандартного ввода с помощью -f -, -fозначающим чтение сценария из файла, и -означающим стандартный ввод, как это обычно происходит со многими командами.

sed -f - "$IN" > "$OUT" << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT

POSIX sed также поддерживает -f, но использование -для стандартного ввода не задокументировано. В этом случае вы можете использовать его /dev/stdinв системах Linux (и, похоже, я помню, что у Solaris это тоже есть, но я не могу подтвердить это прямо сейчас)

Использование <<-SED_SCRIPT(с префиксом '-') позволит SED_SCRIPTсделать отступ для закрывающего тега.

CAMH
источник
Спасибо, то, что вы сказали, сработало, как бы я ни хотел указать, что закрывающий токен не может иметь отступ, иначе это вызывает ошибку в bash, я предполагаю, что это потому, что он также включает пробел в закрывающем.
Тристиан
Обратите внимание, что Apple OS X sed не поддерживает чтение скрипта из стандартного ввода. (По крайней мере, не таким образом или каким-либо другим задокументированным способом.)
Данортон
@danorton: Я добавил решение , которое не требует поддержки -f -в sedно она требует замены процесса: <( command ).
Пабук
5

В случае , если sedне поддерживает чтение сценария из stdin( с помощью -f -), вы можете использовать процесс замены (доступны в bash, zsh, ksh93):

sed "$IN" > "$OUT" -f <( cat << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT)

Закрывающая скобка )должна следовать за конечным разделителем ( SEC_SCRIPT) сразу или после новой строки. В случае замены процесса вы также можете использовать echoвместо документа здесь:

sed "$IN" > "$OUT" -f <( echo \
"    s/a/1/g
    s/test/full/g" )
pabouk
источник
1
В Mac OS X ему не нравился входной файл ( "$IN"или даже testfile.txt), следующий сразу за самой командой sed - он хотел -e scriptили -f file. Переорганизация ответа @pabouk сработала для меня:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
Стивен П
На Max OSX с bash 4.2.45 и стандартным sed BSD закрывающие скобки должны были находиться на новой строке ниже закрывающего SED_SCRIPT.
Александр Климетчек
-1

Может быть, более хороший подход:

OUT=/dev/stdout

IN=my_in_file.txt
sed -s 's/in/out/' < $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT < $IN

IN=my_in_text
sed -s 's/in/out/' <<< $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT <<< $IN

:)

Магнус
источник
1
Интересно, но к тому же дело. ОП хочет передать команды sed через стандартный ввод.
Муру
Этот подход позволяет оба метода, почему downvote?
Магнус
Повторите: «передать команды sed через стандартный ввод». Вы отвечаете, не делает это никаким методом.
Муру