![Awk:提取 RegExp 模式匹配的实际值](https://linux22.com/image/164975/Awk%EF%BC%9A%E6%8F%90%E5%8F%96%20RegExp%20%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D%E7%9A%84%E5%AE%9E%E9%99%85%E5%80%BC.png)
在以下 awk 代码部分中,包含一个文件名及其完整 Linux 路径,其中可能包括YYMMDD 为日期file
类型的目录。backup-YYMMDD
我想将 YYMMDD 分配给isDate[file]
,即isDate[file]=YYMMDD
。
我怎样才能做到这一点?
for (file in files) {
if ( file ~ /(^|\/)(library|labs data|current)(\/|$)/ ) {
isKeep[file]
}
else if ( file ~ /(^|\/)(backup-[0-2][0-9][0-1][0-9][0-3][0-9])(\/|$)/ ) {
isDate[file]
}
else {
isDelete[file]
}
}
答案1
GNUawk
有一个match
命令,允许您提取以模式为特征的字符串组件的实际值。因此,您可以使用
match(file,"^[[:print:]]*(backup-[0-2][0-9][0-1][0-9][0-3][0-9])[[:print:]]*$",pats);
isDate[file]=pats[1]
在else if ....
你的程序的一部分。然后(数组)变量pats
将填充所有(...)
RegExp 中所有包含在字符串中的子表达式,从以下位置开始索引1(pats[0]
将是实际值全部的表达)。由于我们只有一个子表达式,因此分组(backup-YYMMDD
部分),pats[1]
包含您正在寻找的内容。
或者,您可以直接尝试
...
else if (match(file,"^[[:print:]]*(backup-[0-2][0-9][0-1][0-9][0-3][0-9])[[:print:]]*$",pats)==1) {
isDate[file]=pats[1]
}
...
请注意,这种方法当然依赖于只有一个包含模式的路径组件backup-YYMMDD
。
编辑(OP 的注释,@macxpat)
我使用字符串常量 ( "^[[:print:]] ... $"
) 来指定此答案中的正则表达式。然而,正如在GNU Awk 用户指南,将它们指定为正则表达式常量更干净、更高效。因此,更好地利用
match(file,/^[[:print:]]*(backup-[0-2][0-9][0-1][0-9][0-3][0-9])[[:print:]]*$/,pats)
在上面的例子中!