Это может сработать для вас (GNU sed):
sed -n '/AAA\/BBB/{s/\(AAA \?\)\|\(CCC\).*\|./\1\2/g;s/ $//;p}' file
Это решение, предложенное revo , поддерживает порядок строк назначения, см. Ниже решение, которое не имеет, и его описание, на котором основано это улучшенное решение.
sed -n '/AAA\|BBB/!b;s/\(AAA \?\|CCC \?\)\|./\1/g;s/ $//;p' file
Установите параметр -n
, чтобы выборочно печатать пространство шаблона. Если текущая строка не содержит целевой строки, фактически ничего не делайте и замените ее следующей строкой. В противном случае замените цель (за которой следует ноль или один пробел) на себя или удалите следующий символ в пространстве шаблона глобально. В конце удалите все завершающие пробелы и напечатайте пробел. Спасибо revo за оригинальную идею.
N.B. Это не одна строка регулярного выражения,
grep -o 'AAA\|CCC' file
Извлекает целевую строку из каждой строки, но печатает несколько раз в строке, если в строке содержится более одного совпадения, как видно при использовании опции -n
:
grep -no 'AAA\|CCC' file
Если файл (ы) большой, комбинация grep и sed может быть более эффективной:
grep -hnow 'AAA\|CCC' file |
sed -r ':a;$!N;s/^(([^:]*:).*)\n\2/\1 /;ta;s/^[^:]*://;P;D'