用于匹配一组值的 awk 正则表达式

用于匹配一组值的 awk 正则表达式

我在 awk 正则表达式匹配方面遇到问题。我试图将特定列与正则表达式模式匹配(\"\.\"|0|1)。此列只能包含值"."01但是我的正则表达式模式在 awk 中不匹配,而列中的数据是"."。有什么想法吗??

代码

awk -F "$delimitter" -v n="$column" -v m="$pattern" 'NR!=1 && $n !~ "^" m "$" {
                         printf "%s:%s:%s\n", FILENAME, FNR, $n  > "/dev/stderr"
                         count++
                       }
                       END {print count+0}' input.txt 2>> errors.log
                       

答案1

如果您希望模式与任一"."(包含引号)或 完全匹配,01需要模式为^("\."|[01])$or^("[.]"|[01])$^("\."|0|1)$等。

但是,当使用-v将该模式传递给时,您会遇到在那里进行特殊处理awk的问题(对于类似于 的情况也会发生同样的情况),因此您需要在此处转义反斜杠。awk\-F x-v FS=x

最好使用ENVIRON从 shell 传递任意字符串,因为awk这样就不存在这个问题。

所以:

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

(仍然使用-vforn因为这些预计是数字,所以没有反斜杠)。

请注意上面的(, )^x|y$要么x在开头,要么y在结尾。

答案2

匹配文本时不要使用“模式”一词,因为它非常不明确。使用“字符串”或“正则表达式”,无论您指的是哪一个。看如何找到与模式匹配的文本了解更多信息。

听起来你正在解决这个错误,并使用正则表达式比较,其中哈希查找中的字符串比较会更清晰、更不脆弱且更高效。

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

如果任何 shell 变量可以包含转义序列(示例中的变量不包含转义序列),请参阅https://stackoverflow.com/questions/19075671/how-do-i-use-shell-variables-in-an-awk-script除了-v将它们的值传递给 awk 之外的其他方式,例如ENVIRON[]ARGV[]

答案3

尝试[.01]作为你的模式。

这是一个仅匹配., 0, 和 的括号表达式1

注意:在括号表达式之外,您必须转义.as \.(否则它将匹配任何字符),但在括号表达式内它将被视为文字.

相关内容