如果我有一个awk命令
pattern { ... }
和模式使用捕获组,我怎么能访问字符串,所以在块捕获?
如果我有一个awk命令
pattern { ... }
和模式使用捕获组,我怎么能访问字符串,所以在块捕获?
当前回答
注意:gensub的使用不是POSIX兼容的
您也可以在vanilla awk中模拟捕获,不需要扩展。这并不直观:
步骤1。使用gensub将匹配的字符串与一些不出现在字符串中的字符包围起来。 步骤2。对角色使用分裂。 步骤3。拆分数组中的其他每个元素都是捕获组。
$ echo 'ab cb ad' | awk '{ split(gensub(/a./,SUBSEP"&"SUBSEP,"g",$0),cap,SUBSEP); print cap[2]"|" cap[4] ; }' ab|ad
其他回答
我在提出一个bash函数来包装Peter Tillemans的答案时遇到了一些困难,但下面是我想到的:
函数的正则表达式 { Perl -n -e "/$1/ && printf \"%s\n\", " $1 " }
对于下面的正则表达式参数,我发现这比opsb基于awk的bash函数工作得更好,因为我不想打印“ms”。
'([0-9]*)ms$'
我认为gawk match()-to-array仅用于捕获组的第一个实例。
如果您想要捕获多个东西,并对它们执行任何复杂的操作,那么可能
gawk 'BEGIN { S = SUBSEP
} {
nx=split(gensub(/(..(..)..(..))/,
"\\1"(S)"\\2"(S)"\\3", "g", str),
arr, S)
for(x in nx) { perform-ops-over arr[x] } }'
这样就不受gensub()或match()的约束,gensub()限制了修改的复杂性。
通过纯粹的试错,我注意到在unicode模式下gawk的一个警告:对于一个有效的unicode字符串뀇꿬,包含下面列出的6个八进制代码:
场景1:匹配单个字节很好,但也会向您报告多字节的RSTART为1,而不是字节级的答案为2。它也不会提供关于\207是第一个延续字节还是第二个延续字节的信息,因为RLENGTH在这里总是1。
$ gawk 'BEGIN{ print match("\353\200\207\352\277\254", "\207") }'
$ 1
场景2:Match也适用于这样的unicode无效模式
$ gawk 'BEGIN{ match("\353\200\207\352\277\254", "\207\352");
$ print RSTART, RLENGTH }'
$ 1 2
场景3:您可以针对unicode非法字符串检查模式的存在(\300 \xC0对于所有可能的字节对都是UTF8-invalid)
$ gawk 'BEGIN{ print ("\300\353\200\207\352\277\254" ~ /\200/) }'
$ 1
场景4/5/6:错误消息将显示(a) match()与unicode-invalid字符串,index()为任何一个参数为unicode-invalid/incomplete。
$ gawk 'BEGIN{ match("\300\353\200\207\352\277\254", "\207\352"); print RSTART, RLENGTH }' gawk: cmd. line:1: warning: Invalid multibyte data detected. There may be a mismatch between your data and your locale. 2 2
$ gawk 'BEGIN{ print index("\353\200\207\352\277\254", "\352") }' gawk: cmd. line:1: warning: Invalid multibyte data detected. There may be a mismatch between your data and your locale. 0
$ gawk 'BEGIN{ print index("\353\200\207\352\277\254", "\200") }' gawk: cmd. line:1: warning: Invalid multibyte data detected. There may be a mismatch between your data and your locale. 0
那是在回忆的小路上漫步……
很久以前,我用perl替换了awk。
显然,AWK正则表达式引擎没有捕获它的组。
你可以考虑使用这样的代码:
perl -n -e'/test(\d+)/ && print $1'
-n标志使perl像awk一样遍历每一行。
在gawk中,您可以使用match函数来捕获括号中的组。
gawk 'match($0, pattern, ary) {print ary[1]}'
例子:
echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}'
输出的cd。
注意gawk的具体用法,它实现了所讨论的特性。
对于可移植的替代方案,您可以使用match()和substr实现类似的结果。
例子:
echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'
输出的cd。
你可以使用GNU awk:
$ cat hta
RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]
$ gawk 'match($0, /.*(http.*?)\$/, m) { print m[1]; }' < hta
http://www.mysite.net/