Я хочу извлечь подстроку, в которой существует определенный шаблон, из файла, разделенного каналом, поэтому я использовал команду ниже,

awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt

Здесь 'REWARD REQ. ЗАГОЛОВКИ СЕРВЕРА '- это шаблон, который нужно искать в файле и печатать его первые 4 части в строке, разделенной двоеточием.

Теперь я хочу отправить переменную bash, которая будет действовать как образец. поэтому я использовал команду ниже, но она не работает.

awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt

Теперь я хочу отправить переменную bash, которая будет действовать как образец. поэтому я использовал команду ниже, но она не работает.…

40
Chintamani Manjare 8 Сен 2016 в 09:47

3 ответа

Лучший ответ

Проблема здесь не связана с -F.

Проблема заключается в использовании /pat/, когда вы хотите, чтобы pat был переменной. Если вы скажете /pat/, awk понимает это как буквальное "pat", поэтому он попытается сопоставить те строки, которые содержат строку "pat".

Если вы хотите предоставить шаблон через переменную, вам нужно использовать ~ как это:

 awk -v pat="$pattern" '$0 ~ pat'

В целом ваш код должен быть:

awk -v pat="$pattern" -F ":" '$0~pat{print $1, $2, $3, $4 }' file
#                             ^^^^^^

См. Пример:

Учитывая этот файл:

$ cat file
hello
this is a var
hello bye

Поищем строки, содержащие "привет":

$ awk '/hello/' file
hello
hello bye

Давайте теперь попробуем найти "pat", содержащееся в переменной, как вы это делали:

$ awk -v pat="hello" '/pat/' file
$                                    # NO MATCHES!

Теперь воспользуемся выражением $0 ~ pat:

$ awk -v pat="hello" '$0~pat' file
hello                                 # WE MATCH!
hello bye

Конечно, вы можете использовать такие выражения, чтобы сопоставить только одно поле и сказать awk -v pat="$pattern" '$2 ~ pat' file и так далее.

Из Руководства пользователя GNU Awk → 3.1 Как использовать регулярные выражения :

Когда регулярное выражение заключено в косую черту, например / foo /, мы называем его константой регулярного выражения, подобно тому как 5.27 - это числовая константа, а «foo» - строковая константа.

И Руководство пользователя GNU Awk → 3.6 Использование динамических регулярных выражений:

Правая часть оператора «~» или «! ~» Не обязательно должна быть константой регулярного выражения (т. Е. Строкой символов между косыми чертами). Это может быть любое выражение. Выражение вычисляется и при необходимости преобразуется в строку; содержимое строки затем используется как регулярное выражение. Регулярное выражение, вычисленное таким образом, называется динамическим регулярным выражением или вычисленным регулярным выражением:

BEGIN { digits_regexp = "[[:digit:]]+" }
$0 ~ digits_regexp    { print }

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

54
fedorqui 'SO stop harming' 8 Сен 2016 в 06:59
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt

Вы не можете использовать переменную внутри нотации регулярного выражения // (нет никакого способа отличить ее от поиска pat); вы должны указать, что переменная является регулярным выражением, с помощью оператора ~ (сопоставления).

6
Jonathan Leffler 8 Сен 2016 в 06:53

Это своего рода хакерский прием, но он упрощает мне жизнь.

cmd="awk '/$pattern/'"
eval $cmd

Сделав его сначала строкой, вы сможете манипулировать им, выходя за границы awk

1
Ryan Donahoe 18 Сен 2017 в 17:19