Регулярное выражение Awk для сопоставления набора значений

Я бы предложил использовать

<delete-pattern>

вместо

<tag-pattern>

, потому что, когда шаблон не совпадает,

<delete-message>

удалит первое сообщение в списке, даже если оно не соответствует желаемому шаблону.

0
01.07.2021, 17:02
3 ответа

Если вы хотите, чтобы шаблон точно совпадал с"."(с включенными кавычками ), 0или 1, шаблон должен быть ^("\."|[01])$, или ^("[.]"|[01])$, или ^("\."|0|1)$. и т. д.

Но при использовании -vдля передачи этого шаблона в awkу вас возникает проблема, заключающаяся в том, что awkобрабатывает \специально там (то же самое происходит с -F x, что похоже на -v FS=x), поэтому вам нужно избежать обратной косой черты здесь.

Лучше использовать ENVIRONдля передачи произвольных строк из оболочки в awk, так как это не создает такой проблемы.

Так:

pattern='"\."|0|1'
PATTERN=$pattern DELIMITER=$delimiter awk -v n="$n" '
  BEGIN {FS = ENVIRON["DELIMITER"]; m = ENVIRON["PATTERN"]}
  $n ~ "^(" m ")$" {...}'

(по-прежнему используется -vвместо n, так как ожидается, что это числа, поэтому без обратной косой черты ).

Обратите внимание на (, )выше. ^x|y$будет либо xв начале, либо yв конце.

2
28.07.2021, 11:21

Попробуйте [.01]в качестве шаблона.

Это выражение в квадратных скобках, которое соответствует только ., 0и 1.

ПРИМЕЧАНИЕ. :вне выражения в квадратных скобках вам нужно экранировать .как \.(, иначе он будет соответствовать ЛЮБОМУ символу ), но внутри выражения в квадратных скобках он будет рассматриваться как литерал.

0
28.07.2021, 11:21

Не используйте слово «шаблон» при сопоставлении текста, так как оно может быть неоднозначным. Используйте «строку» или «регулярное выражение», в зависимости от того, что вы имеете в виду. См. , как -найти -и -найти -текст --, который -соответствует -шаблону -для получения дополнительной информации.

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

valid='"."|0|1'
awk -F "$delimitter" -v n="$column" -v m="$valid" '
    BEGIN {
        split(m,tmp,"|")
        for (i in tmp) {
            valid[tmp[i]]
        }
    }
    NR>1 && !($n in valid) {
        printf "%s:%s:%s\n", FILENAME, FNR, $n  > "/dev/stderr"
        count++
    }
    END {print count+0}
' input.txt

Если какая-либо из переменных оболочки может содержать escape-последовательности (, которые в вашем примере не содержат ), тогда см.https://stackoverflow.com/questions/19075671/how-do-i-use-shell-variables-in-an-awk-scriptдля других способов, кроме -v, для передачи их значений в awk, например. ENVIRON[]или ARGV[].

1
28.07.2021, 11:21

Теги

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