Я бы предложил использовать
<delete-pattern>
вместо
<tag-pattern>
, потому что, когда шаблон не совпадает,
<delete-message>
удалит первое сообщение в списке, даже если оно не соответствует желаемому шаблону.
Если вы хотите, чтобы шаблон точно совпадал с"."
(с включенными кавычками ), 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
в конце.
Попробуйте [.01]
в качестве шаблона.
Это выражение в квадратных скобках, которое соответствует только .
, 0
и 1
.
ПРИМЕЧАНИЕ. :вне выражения в квадратных скобках вам нужно экранировать .
как \.
(, иначе он будет соответствовать ЛЮБОМУ символу ), но внутри выражения в квадратных скобках он будет рассматриваться как литерал.
Не используйте слово «шаблон» при сопоставлении текста, так как оно может быть неоднозначным. Используйте «строку» или «регулярное выражение», в зависимости от того, что вы имеете в виду. См. , как -найти -и -найти -текст --, который -соответствует -шаблону -для получения дополнительной информации.
Похоже, вы делаете это неправильно и используете сравнение регулярных выражений, где сравнение строк в поиске по хешу было бы более четким, менее хрупким и более эффективным.
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[]
.