首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于字符串替换和打印匹配和不匹配字符串的awk命令

用于字符串替换和打印匹配和不匹配字符串的awk命令
EN

Stack Overflow用户
提问于 2021-08-02 01:08:40
回答 3查看 192关注 0票数 2

我希望用来自File-1的匹配字符串替换File-2中的多个字符串(超过1000)

File-1

代码语言:javascript
复制
Geneid Length s1 s2
1_1 6571 7 8
1_2 5041 3 0
1_3 1032 7 3    
1_4 1212 3 5    
1_5 1071 3 5    
2_1 7171 2 7
2_2 1038 1 1
2_3 9361 0 6
2_4 1056 5 1

File-2 (地图):

代码语言:javascript
复制
1_1
1_2 k0002
1_3
1_4
1_5 k0006   
2_1
2_2
2_3
2_4 k0528

预期产出:

代码语言:javascript
复制
Geneid Length s1 s2
1_1 6571 7 8
k0002 5041 3 0
1_3 1032 7 3    
1_4 1212 3 5    
k0006 1071 3 5  
2_1 7171 2 7
2_2 1038 1 1
2_3 9361 0 6
k0528 1056 5 1

我使用了以下awk命令:

代码语言:javascript
复制
awk '
NR==FNR {                      
a[$1]=$2                    
next                       
}
{                               
print (($1 in a)?a[$1]:$1, $2, $3, $4)  
}' File-2 File-1 > File-3

这给了我这个:

代码语言:javascript
复制
Geneid  Length  s1  s2
 6571 7 8
k0002 5041 3 0
 1032 7 3   
 1212 3 5   
k0006 1071 3 5  
 7171 2 7
 1038 1 1
 9361 0 6
k0528 1056 5 1

如何修改这个awk命令以保持不匹配的字符串?

对不起,我是linux和awk的新手(试着学习)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-02 05:38:22

表达式($1 in a)?a[$1]:$1将打印a[$1]$1,具体取决于$1是否是a中的键。但是您的所有键都在a中,因此,例如,对于键1_1,它会打印空字符串,这是a["1_1"]的值。解决方案是,只有在要为a中的键添加值时才填充$1

代码语言:javascript
复制
awk 'NR==FNR { if (NF > 1) a[$1]=$2; next }
{ print (($1 in a)?a[$1]:$1, $2, $3, $4) }' File-2 File-1

对于调试像您这样的脚本,可以在不同的点添加print语句来查看脚本正在做什么。以下是我最后所做的,以找出你的脚本有什么问题。

代码语言:javascript
复制
# STILL BUGGY, DEBUGGING RUN
awk 'NR==FNR { print("a[" $1 "]=" $2); a[$1]=$2; next; }
{ print ($1 in a ? a[$1] : $1), $2, $3, $4, ($1 in a), a[$1], $1, ($1 in a ? "yes" : "no"), "end" }' File-2 File-1
票数 2
EN

Stack Overflow用户

发布于 2021-08-02 06:08:56

代码语言:javascript
复制
$ awk '
    NR==FNR { if (NF>1) a[$1]=$2; next }
    $1 in a { $1=a[$1] }
1' file2 file1
Geneid Length s1 s2
1_1 6571 7 8
k0002 5041 3 0
1_3 1032 7 3
1_4 1212 3 5
k0006 1071 3 5
2_1 7171 2 7
2_2 1038 1 1
2_3 9361 0 6
k0528 1056 5 1

  1. if (NF>1)有效地确保您只使用您需要的来自file2的值填充a[],即那些有第二个字段的值,
  2. $1 in a确保您只在file2中存在关联条目时才从file中更改$1。不要测试a[$1]==""或任何类似的东西,因为这将为file1中的每个$1填充a[],因此耗尽内存并在最后增加执行a[]会导致打印当前(可能只是修改过的) file1行。
票数 1
EN

Stack Overflow用户

发布于 2021-08-02 04:27:07

考虑到File-2不会是空的:

代码语言:javascript
复制
awk 'NR==FNR{a[$1]=$2;next}a[$1]!=""{$1=a[$1]}1' File-2 File-1
Geneid Length s1 s2
1_1 6571 7 8
k0002 5041 3 0
1_3 1032 7 3
1_4 1212 3 5
k0006 1071 3 5
2_1 7171 2 7
2_2 1038 1 1
2_3 9361 0 6
k0528 1056 5 1

如果它可以是空的,并且使用GNU awk,您可以用ARGIND==1FILENAME=="File-2"替换NR==FNR

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68615471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档