Как вывести только тот столбец, у которого есть постоянные соседи?

Как вывести только тот столбец, у которого есть постоянные соседи?

ВХОД

AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU

ВЫХОД

Y1Y
Y2Y

Входные строки могут меняться.. только XXX перед Y1Y и ZZZ после Y1Y постоянны (они соседствуют с XXX и ZZZ, как здесь). Y1Y может быть чем угодно, например: Y1Y, Y2Y, Y1T и т. д.

В:как мне получить ВЫВОД с помощью awk, sed или grep? (или есть ли какой-то лучший инструмент для этого?)

ОБНОВЛЯТЬ(проблема): почему не работает, если в Y1Y есть «.»?

[user@notebook ~] echo 'XXX Y1Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
Y1Y
[user@notebook ~] echo 'XXX Y1.Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
[user@notebook ~] 

решение1

grepДля этого вы можете использовать предоставляемую им возможность PCRE:

$ grep -Po "(?<=XXX )\S+(?= ZZZ)" data.txt 
Y1Y
Y2Y

Подробности

Это решение использует функцию просмотра назад и вперед PCRE, которая может сопоставлять строки фиксированной длины.

Вышеуказанный код смотрит за каждым \w+, чтобы увидеть, является ли он XXXи заголовком каждого, \w+чтобы увидеть, является ли он ZZZ. Если это так, то это совпадение. Переключатель -oto grepсообщает ему, что нужно выводить только совпадения, т. е \w+. .

Дополнение, можно ли это сделать с помощью sed?

Я не думаю, что эту проблему можно решить с помощью sed. Я вижу два подхода.

  1. сохранить потенциальные совпадения в дополнительной переменной, если вы встретите ZZZ, то выведите их
  2. s/XXX ..наша строка.. ZZZ/ ..наша строка../

№ 1 кажется довольно объемной работой, поэтому я даже не буду пытаться ее выполнить. Вот что происходит с подходом № 2.

$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt 
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU

Так что он может найти совпадения просто отлично, но ничего не делает для строк, которые не совпадают. Может быть, есть способ указать sedудалить эти строки, в этом случае это было бы альтернативным решением.

Связанный контент