LINUX.ORG.RU

awk, как корректно экранировать внутреннюю переменную?

 


1

2

В regexp'ах awk'а при работе с шелл-переменными можно сделать, например, так:

awk '/'$1'/{bla}'


При этом конструкция вида

awk '/^'$1'/{bla}'


будет работать. Как то же самое сделать для внутренней переменной? Т.е., есть у нас некий var. Как мне сделать

awk '/^var/{bla}'


Для поиска соответствия внутренней переменой обычно предлагаются варианты в стиле $0 ~ var, но мне нужно более точное соответствие. Собственно, сабж.

★★★★★

Ответ на: комментарий от evilface

Не то. Мне не нужно искать соответствие var regex'у, мне тупо надо добавить ^ к var при поиске, чтобы отсеять лишние значения в обрабатываемом файле.

Т.е., var - это и есть мой regex, мне лишь надо дописать к нему спецсимвол.

YAR ★★★★★
() автор топика
Последнее исправление: YAR (всего исправлений: 1)
Ответ на: комментарий от YAR

В awk конкатенация делается с помощью пробела.

Соответственно, в вашем случае попытки сделать

/^var$/ {bla}


превращаются в
if (match($0, "^" var "$")) {bla}


Да, мой косяк, что перепутал и var и есть регексп.

evilface ★★
()
Ответ на: комментарий от evilface

Собственно, поясню мою задачу:

В шелл-варианте:

rain@debian:~$ var=174b; awk '/^'$var'/{print}' /usr/share/misc/pci.ids
174b  PC Partner Limited / Sapphire Technology


В моем случае значение для поиска определяется уже внутри awk (ему скармливаются несколько файлов - вендор, девайс и база), соответственно и ищется все внутри одного процесса. Но

 awk 'BEGIN {var="174b"} $1 == var {print}' /usr/share/misc/pci.ids 

Выдает в том числе строки, которые имеют табуляцию в начале, а это уже не соответствует тому, что мне надо.

YAR ★★★★★
() автор топика
Ответ на: комментарий от YAR

Вот, набросал пример:

$ echo 'abc
d
b
        b' | awk '{var="b"; if (match($0, "^" var "$")) { print "Found:", $0 }}'
Found: b

Здесь присутствует и b в строке, и чисто b но с табуляцией. Не важно, в какой момент определяется var, по адресу BEGIN или как у меня.

Просто вместо подстановки переменной в адрес, можно использовать if(match….

evilface ★★
()
Ответ на: комментарий от evilface

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

YAR ★★★★★
() автор топика
Ответ на: комментарий от futurama

Да, спасибо за форматирование. Я поленился, ибо в консоли в одну строчку удобнее, а ЛОР широкий, а скрипт маленький.

Разве что при многострочной записи «;» не нужна.

evilface ★★
()
Ответ на: комментарий от YAR

Проще было бы, если бы переменные спокойно вставлялись в адрес, но я так не умею. На счёт умеет ли это хитрым образом делать сам awk — не знаю. Взял бы if и match.

evilface ★★
()
Ответ на: комментарий от YAR

Стоп, а в var сгенерирован регексп или просто статическая строка, с которой надо сравнить?

Если последнее, то можно так:

$ echo 'abc
d
b
        b' | awk 'BEGIN {var="b"} {if ($0 == var) { print "Found:", $0 }}'
Found: b


Или, без if'а в многострочек, в стиле предложенного выше:
$ echo 'abc
d
b
        b' | awk 'BEGIN {var="b"};
                  var == $0 {  
                         print "Found:", $0
                  }'
Found: b

evilface ★★
()
Последнее исправление: evilface (всего исправлений: 2)
Ответ на: комментарий от evilface

Тут писал уже: awk, как корректно экранировать внутреннюю переменную? (комментарий)

Это строка, но надо добавить ^ в начале. Для экранированной шелл-переменной работает, как это сделать для внутренней - неизвестно: не выводит либо совсем ничего, либо ругается на синтаксис.

YAR ★★★★★
() автор топика
Ответ на: комментарий от YAR

Тогда с match и $0, так как $1 — это уже первое поле после разбора, то есть с выкинутыми пробелами/табами до и после.

evilface ★★
()

При этом конструкция вида .. будет работать

кривая конструкcция: с тем же успехом можно выхлопнуть внутреннюю переменную и сгенерировать скрипт

$0 ~ var, но мне нужно более точное соответствие

вполне себе точное, только обрабатывается как строка, а потом regexp (наподобие ".." vs r".." в питоне); а в предыдущем случае строка парсится шеллом

anonymous
()
Ответ на: комментарий от anonymous

О. Вот за это спасибо. Причем, пробовал такой вариант, только вот с $1. Теперь понял ошибку.

YAR ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.