首页 > 解决方案 > 仅当行不包含特定字符串时才在行内查找/替换 (awk)

问题描述

我正在尝试使用不同的语法重现 awk 命令。我有一个test.txt看起来像这样的文件 ( ):

>NAME_123_CONSENSUS
GACTATACA
ATACTAGA
>NAME2_48_TEST
ATAGCGA

我希望使用不同的awk语法将所有出现的“A”替换为“1”。我可以使用以下行来解决这个问题:

awk '!/_/{gsub("A", "1"); 1' test.txt

但是,我无法使用for循环获得相同的结果,

awk '{for(j=1; j<=NF; j++) if ($j ~ "_") print; else print gsub("A","1")}' test.txt

也不使用以下输入

awk '{ if ($0 ~ "_") print $0; else print gsub("A", "1"); }' test.txt

这两个最后的命令都给出以下输出。为什么他们给出不同的输出,我缺少什么让最后两个命令都给出所需的输出?

>NAME_123_CONSENSUS
4
4
5
>NAME2_48_TEST
3

标签: awk

解决方案


您在gsub()这里错误地使用了该功能。sub()/函数返回所做的gsub()替换次数,而不是修改后的字符串。您将要修改的字符串设置为最后一个参数并将其打印回来

awk '{ for(j=1; j<=NF; j++) if ($j ~ "_") print; else { gsub("A","1",$0); print } }'

也就是说,您的第一个命令是最有效/最简洁的编写方式。}请注意,您在 OP中缺少 a 。它应该写成

awk '!/_/{ gsub("A", "1") }1'

或者使用gensub()GNU Awk 中的 available 返回修改后的字符串,您可以使用print. 在GNU Awk 的字符串函数中查看更多信息

awk '{ for(j=1; j<=NF; j++) if ($j ~ "_") print; else print gensub(/A/, "1", "g") }'

推荐阅读