Как сохранить совпавший шаблон в переменную с помощью команды "sed"?

Я пытаюсь найти шаблон, используя sed командовать в file.txt между первым char1 и char2, а затем замените его на строку. как ниже с echo Пример режима:

echo "This X is test Y. But X is not test Y." | sed 's/X[^Y]*Y/REPLACE/'

Также мне нужно сохранить совмещенный шаблон (например, is test {<- пробелы вокруг важны}) в переменной.

2 ответа

Решение

Вот единственный вызов sed, который записывает исправленную строку в стандартный вывод, сохраняя удаленный текст в переменной оболочки. var:

$ var=$(echo "This X is test Y. But X is not test Y." | sed -nr 'h;s/[^X]*X([^Y]*)Y.*/\1/;p;x;s/X[^Y]*Y/REPLACE/;w /dev/stderr') 2>&1
This REPLACE. But X is not test Y.

Значение var является:

$ echo "==$var=="
== is test ==

Объяснение:

  • h

    Эта команда копирует текущий шаблон в область удержания.

  • s/[^X]*X([^Y]*)Y.*/\1/;p

    Это удаляет все из пространства шаблона, кроме текста между первым X а также Y включая любые пробелы. Затем он печатается на стандартный вывод. Это вывод, который захватывается оболочкой и присваивается var,

  • x

    Это копирует пространство удержания обратно в пространство образца. Когда это будет сделано, пространство шаблона содержит копию исходной строки ввода.

  • s/X[^Y]*Y/REPLACE/; w /dev/stderr

    Замена сделана, и результат записан stderr,

  • 2>&1

    После того, как оболочка захватила стандартный вывод в var, это дает команду оболочке скопировать stderr (который имеет строку с REPLACE) в stdout.

Помимо обработки переменных var

Переменная var включает в себя ведущие и конечные пробелы. Если оболочка была впоследствии предметом var до разделения слов эти пробелы будут удалены. Чтобы предотвратить это, когда var ссылка сделана внутри двойных кавычек, как в примере выше.

Вы должны выполнить это с помощью второй команды sed:

var=$(echo "This X is test Y. But X is not test Y." | \
tee >(sed 's/X[^Y]*Y/REPLACE/' >/dev/stderr) | \
sed -r 's/[^X]*X([^Y]*)Y.*/\1/')

Exlanation:

  • Вы должны использовать tee разделить поток. Что оба stdout а также stderr содержать строку.
  • tee нужен файл в качестве аргумента. Мы даем tee труба где sed слушает и заменяет строку.
  • sed печатает строку в stderr: Вывод, который вы видите в терминале.
  • Второй sed команда слушает stdout и извлекает необходимую строку, которая теперь сохраняется в переменной $var (контекст stdout).

Используйте это, чтобы проверить:

$ echo ">$var<"
> is test <
Другие вопросы по тегам