Как найти и вывести соответствующее значение совпадения из командной строки?

This relevant documentation предполагает, что существует магия systemd для монтирования других и более разделов, чем те, которые упомянуты в /etc/fstab.

Средством против этой магии будет следующая последовательность команд:

# mkdir -p /etc/systemd/system-generators
# ln -s /dev/null /etc/systemd/system-generators/systemd-gpt-auto-generator

4
23.01.2017, 13:23
2 ответа

Учитывая предположение, что все ваши строки сформированы одинаково (или, по крайней мере, все строки, содержащие MATCH: ), кажется, что ПОИСКПОЗ: - это 5-й элемент строки, а желаемое значение - 6-й.

Поэтому в awk вам просто нужно проверить, равен ли 5-й элемент MATCH: , и вывести 6-й элемент строки, если он правильный.

$ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ if ($5 == "MATCH:") print $6 }' 
    10

РЕДАКТИРОВАТЬ: Учитывая предположение, MATCH: может быть где угодно в строке:

  $ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}' 
10

Может быть не очень элегантно, но вам нужно пройти через все поля строки и проверить каждое поле, которое является выполняется с помощью цикла for и теста if . Если тестовое поле соответствует, то распечатайте следующее поле.

Я просто добавил разрыв, чтобы напрямую перейти к следующей строке и продолжить текущую итерацию поля.

В многострочном файле:

$ cat terst 
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 11 [text]
2017-01-19:31:51 [ABCD:] 37723 - [text]
2017-01-19:31:51 37723 - MATCH: 12 [text]
$ awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}' terst 
10
11
12
2
27.01.2020, 20:47
sed -n 's/.* MATCH: \([^ ]*\).*/\1/p'

Будет печатать последовательность непробельных символов, следующих за крайним правым вхождением «MATCH:» в каждая совпадающая строка.

-n сообщает sed не печатать пространство шаблонов по умолчанию. А флаг p в команде s указывает sed напечатать пространство шаблонов (то есть результат подстановки), если подстановка успешна.

Итак:

sed -n 's/pattern/replacement/p'

- это обычная идиома для вывода результатов успешных замен.

Обратите внимание, что вышесказанное предполагает, что введенный текст является допустимым. Поскольку . * соответствует любой последовательности из символов , он не будет соответствовать последовательностям байтов, которые не образуют допустимые символы. Обычно это происходит в языковых стандартах UTF-8 при обработке текста в другой кодировке. В таком случае вы можете добавить к этой строке префикс LC_ALL = C . Это заставляет sed обрабатывать каждый байт как символ, поэтому недопустимая последовательность байтов отсутствует. Здесь это сработает, поскольку все символы, которые мы сопоставляем, взяты из переносимого набора символов.

Стандартный awk не имеет ничего эквивалентного, поскольку он не поддерживает группы захвата ( \ (... \) , захваченный в \ 1 ) в своей функции sub () .

Здесь вам нужно прибегнуть к функции match () :

awk 'match($0, / MATCH: [^ ]*/) {
       print substr($0, RSTART+8, RLENGTH-8)}'

Или использовать такие уловки, как:

awk -F ' MATCH: ' 'NF>1 {sub(/ .*/, "", $2); print $2}'

(имейте в виду, что они будут учитывать крайнее левое вхождение «МАТЧ:» ).

GNU awk имеет функцию gensub () , которая имеет функциональность, аналогичную команде s в sed , но с ошибкой в ​​конструкции. в нем не говорится, была ли произведена замена. Здесь вы можете сделать:

 gawk '(replacement = gensub(/.* MATCH: ([^ ]*).*/, "\\1", 1)) != $0 {
   print replacement}'
9
27.01.2020, 20:47

Теги

Похожие вопросы