AWK - 有没有办法部分匹配数字字符串?

时间:2013-05-16 20:52:22

标签: regex bash awk matching

我在使用数字常量(由参数给出)匹配某些行时遇到了一些麻烦。例如,给定文件中的以下数据:

0.6880228954232877  0.2284901699470367  0.3868277922222205   T   T   T
0.7303175733143661  0.3618318512370564  0.3974056922222218   T   T   T
0.0000000000000000  0.0000000000000000  0.0000000000000000   T   T   T
0.0000000000000000  0.3333333333333357  0.0000000000000000   T   T   T
0.0000000000000000  0.6666666666666643  0.0000000000000000   T   T   T
0.8333728559007199  0.8332938107659444  0.0000000000000000   T   T   T
0.5226283985455709  0.2857115516559929  2.3313236566666689   T   T   T
0.1621334092166649  0.4671478452296256  2.3549492962962972   T   T   T
0.6160582554738738  0.3498000553315919  2.3391425111111133   T   T   T
0.7070022591099487  0.3040360596000298  2.3690645440740710   T   T   T
0.5183050106710922  0.2156253703264568  2.2883209644444449   T   T   T
0.5226283985455709  0.2857115516559929  3.3313236566666689   T   T   T
0.1621334092166649  0.4671478452296256  3.3549492962962972   T   T   T
0.6160582554738738  0.3498000553315919  3.3391425111111133   T   T   T
0.7070022591099487  0.3040360596000298  3.3690645440740710   T   T   T
0.5183050106710922  0.2156253703264568  3.2883209644444449   T   T   T

我想匹配第三个字段以“2.”开头的行,然后将这些行的字母“T”简单替换为“F”。

我尝试了多次尝试但是失败了,例如:awk (注意,第一个$ 1是bash参数,它给出了模式“2”。

 awk -v pattern=$1 ' $3 ~ pattern { print $1,$2,$3" F F F"  }' file 

不起作用。

我尝试的另一种选择是代替模式“2”,只是“2”,所以表达式变为:

 awk -v pattern=$1 ' $3 ~ /pattern\./ { print $1,$2,$3" F F F"  }' file 

但它也不起作用。任何建议都非常感谢。

4 个答案:

答案 0 :(得分:3)

我希望我能正确理解你的问题。我不明白为什么你分配变量pattern,但从未使用它。

使用您的示例数据,此行有效:

 awk '$3~/^2/&&$4=$5=$6="F"' file  

awk '$3~/^2/{gsub(/T/,"F");print}' file

输出:

kent$  awk '$3~/^2/&&$4=$5=$6="F"' file   
0.5226283985455709 0.2857115516559929 2.3313236566666689 F F F
0.1621334092166649 0.4671478452296256 2.3549492962962972 F F F
0.6160582554738738 0.3498000553315919 2.3391425111111133 F F F
0.7070022591099487 0.3040360596000298 2.3690645440740710 F F F
0.5183050106710922 0.2156253703264568 2.2883209644444449 F F F

kent$  awk '$3~/^2/{gsub(/T/,"F");print}' file
0.5226283985455709  0.2857115516559929  2.3313236566666689   F   F   F
0.1621334092166649  0.4671478452296256  2.3549492962962972   F   F   F
0.6160582554738738  0.3498000553315919  2.3391425111111133   F   F   F
0.7070022591099487  0.3040360596000298  2.3690645440740710   F   F   F
0.5183050106710922  0.2156253703264568  2.2883209644444449   F   F   F

修改

awk -v p="^2" '$3~p{gsub(/T/,"F");print}' file

如果您的模式存储在shell var:

pattern="^2"
awk -v p="$pattern" '$3~p{gsub(/T/,"F");print}' file

答案 1 :(得分:1)

以下内容适用于gnu awk

awk -v pattern='^2\\.' ' $3 ~ pattern {print($0)}' samp.t
0.5226283985455709  0.2857115516559929  2.3313236566666689   T   T   T
0.1621334092166649  0.4671478452296256  2.3549492962962972   T   T   T
0.6160582554738738  0.3498000553315919  2.3391425111111133   T   T   T
0.7070022591099487  0.3040360596000298  2.3690645440740710   T   T   T
0.5183050106710922  0.2156253703264568  2.2883209644444449   T   T   T

答案 2 :(得分:1)

您的错误可能是您创建变量pattern,但使用变量zlevel。您还需要锚定表达式(^以匹配字符串的开头),否则任何包含2的行都将匹配。以下应该有效:

e="2\."
awk -v pattern="^${e//\\/\\\\}" '$3 ~ pattern {gsub(/T/, "F", $0); print}'

${e//\\/\\\\}仅用于转义反斜杠,因此正则表达式不会变得比必要的复杂。

答案 3 :(得分:1)

以下awk将允许从第三列以2开始的行开始打印。然后,您可以根据需要将T替换为F.

awk '{
if ($3 ~ "^2\..*") { print $0 }
}'

此外,sed可能更适合此问题(因为这是搜索替换类型问题):

这样的事情可以做你想要的事情:

sed 's/\(.*\) \(.*\) \(2\.[0-9]*\) \(.*\)/\1 \2 \3   F   F   F/g'