我希望能够使用常规表达式来匹配文件中的以下行
## FAML [ASMB]
## FAML [ASMB] KYA
## FAML [ASMB] KYA,KYB
然后能够捕获FAML
,的值ASMB
以及逗号分隔关键字的序列KYA,KYB
。
用户提供FAML
、ASMB
、 以及他们想要匹配的任何关键字KYA,KYB
等。
我在做
BEGIN {
kw=".*" ; ebl="[[]" ; ebr="[]]" ; spc="[[:space:]]*"
pn_ere = "^[[:space:]]*([#;!]+|@c|//)[[:space:]]+"
fm = "%s(%s) %s(%s)%s(%s)%s$"
beg_ere = sprintf(fm, pn_ere, faml, ebl, asmb, ebr, kw, spc)
}
$0 ~ beg_ere {
fml = gensub(beg_ere, "\\2", 1, $0)
asm = gensub(beg_ere, "\\3", 1, $0)
kyw = gensub(beg_ere, "\\4", 1, $0)
}
其中(%s)
用于捕获文件中的fml
、asm
和 ,以匹配、和的任何用户输入。kyw
faml
asmb
kw
##
行匹配将对以双注释字符, ;;
, !!
, //
,开头的注释部分中的源代码文件执行@c
。
因此用户可以调用
awk -f densel -v faml="HD" -v asmb="OPCON" galex.el
例如,考虑一个 emacs lisp 文件galex.el
。
;; HD [TEST]
(defun galex-insert (n)
"Copy line N at current point.
N is the numeric prefix arg"
(interactive "p")
(save-excursion
(goto-char (point-min))
(forward-line (1- n))
(kill-ring-save (line-beginning-position) (line-end-position))))
;; HD [OPCON]
(message "\nGALEX")
;; HD [OPCON] elisp,resource
(message "\nGALEX")
然后正则表达式将匹配行;; HD [OPCON]
和;; HD [OPCON] elisp,resource
。
如果用户指定
awk -f densel -v faml="HD" -v asmb="OPCON" -v kw="resource" galex.el
只有以下行会匹配
;; HD [OPCON] elisp,resource
答案1
你的问题不清楚,但这可能就是你想要做的(使用 GNU awk 作为第三个参数match()
):
$ cat tst.awk
BEGIN {
re = "#+ ([^ ]+) ([[][^]]*]) *(.*)"
}
match($0,re,a) {
for (i=1; i in a; i++) {
print i, a[i]
}
print ""
}
$ awk -f tst.awk file
1 FAML
2 [ASMB]
3
1 FAML
2 [ASMB]
3 KYA
1 FAML
2 [ASMB]
3 KYA,KYB
显然,只需将您喜欢的任何变量分配给 等的内容即可a[1]
。
更改正则表达式以满足您的需求,这只是为了以最小的方式演示我认为的问题和解决方案,并向您展示如何创建最小可重复示例如果/当您将来需要提出其他问题时。
参见match()
https://www.gnu.org/software/gawk/manual/gawk.html#String-Functions该函数的作用。