我想计算文档中的字符串数量。
如果输入为:
GGTGGTGGTAT
GGTAGTGGTAT
GGTGGTGGTAT
GGTAATGGTAT
我搜索GGTGGTGGT我想找到3场比赛。允许一个歧义。
使用egrep看起来像这样,输出为3。
egrep -c "GGTGGTGGT|.GTGGTGGT|G.TGGTGGT|GG.GGTGGT|GGT.GTGGT|GGTG.TGGT|GGTGG.GGT|GGTGGT.GT|GGTGGTG.T|GGTGGTGG." input
答案 0 :(得分:4)
以下是使用bash生成该正则表达式的方法:
$ patt=(GGTGGTGGT)
$ for ((i=0; i<${#patt[0]}; i++)); do
patt+=( "${patt[0]:0:i}.${patt[0]:i+1}" )
done
$ regex=$(IFS='|'; echo "${patt[*]}")
$ echo "$regex"
GGTGGTGGT|.GTGGTGGT|G.TGGTGGT|GG.GGTGGT|GGT.GTGGT|GGTG.TGGT|GGTGG.GGT|GGTGGT.GT|GGTGGTG.T|GGTGGTGG.
然后:
awk -v regex="$regex" '$0 ~ regex' file
或仅使用awk:
awk -v srch=GGTGGTGGT '
BEGIN {
regex = srch
for (i=1; i<=length(srch); i++)
regex = regex "|" substr(srch,1,i-1) "." substr(srch, i+1)
}
$0 ~ regex
' << END
GGTGGTGGTAT
GGTAGTGGTAT
GGTGGTGGTAT
GGTAATGGTAT
END
GGTGGTGGTAT
GGTAGTGGTAT
GGTGGTGGTAT
答案 1 :(得分:2)
这个awk可执行脚本将创建匹配的模式,然后测试每一行以计算匹配:
#!/usr/bin/awk -f
BEGIN { createPatternArray( pattern, a ) }
{
for( k in a ) { if( $0 ~ k ) { total++; break } }
}
END { print total }
function createPatternArray( pattern, a, pLen, i ) {
a[pattern]
pLen = length( pattern )
for(i=1; i<=pLen; i++) {
a[substr(pattern,1,i-1) "." substr(pattern,i+1)]
}
# for( k in a ) { print k }
}
如果它放在像awko
这样的文件中(并且是可执行的),那么在数据上运行它就像:
awko -v pattern=GGTGGTGGT data
3
createPatternArray
函数使数组中的条目如下:
.GTGGTGGT
G.TGGTGGT
GG.GGTGGT
GGT.GTGGT
GGTG.TGGT
GGTGG.GGT
GGTGGT.GT
GGTGGTG.T
GGTGGTGG.
GGTGGTGGT
对于每一行,将根据数组中的条目测试该行的前缀。如果匹配,则增加totals
然后中断(否则会有多个匹配)。在END
,打印total
。
答案 2 :(得分:1)
必要的awk模式与你的egrep解决方案相同:
awk '/GGTGGTGGT|.GTGGTGGT|G.TGGTGGT|GG.GGTGGT|GGT.GTGGT|GGTG.TGGT|GGTGG.GGT|GGTGGT.GT|GGTGGTG.T|GGTGGTGG./{print $0}' input
答案 3 :(得分:1)
这是使用(G)awk和gensub函数
的方法awk -va="GGTGGTGGT" '
{for(i=1;i<=length(a);i++)if($0~gensub(/./,".",i,a)){print;next}}' file
GGTGGTGGTAT
GGTAGTGGTAT
GGTGGTGGTAT
-va="GGTGGTGGT"
将变量a设置为引号中包含的值(无论您想要什么)
{for(i=1;i<=length(a);i++)
创建一个从1到变量a长度的循环。长度是字符串内的字符数。
if($0~gensub(/./,".",i,a))
我先解释一下gensub
前两个args用文字.
交换.
(任何字符)。第三个参数是来自参数1的匹配的发生。当我们搜索单个字符时,这将仅通过字符串移动,用.
替换每个字符。最终的arg是要编辑的字符串,并使用a
。 gensub
也会返回字符串,而不是编辑原始字符串。
$0~
表示整行包含~
这些都包含在if中,当两个评估结果都将导致
时$0~.GTGGTGGT
$0~G.TGGTGGT
$0~GG.GGTGGT
$0~GGT.GTGGT
$0~GGTG.TGGT
$0~GGTGG.GGT
$0~GGTGGT.GT
$0~GGTGGTG.T
$0~GGTGGTGG.
{print;next}
如果其中任何一个匹配,则该行将被打印,并且将跳过所有其他指令并处理下一行。
https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html
答案 4 :(得分:0)