我有两个文件:
file1.txt
dn_id101_400_CT_TC string1
dn_id111_60_TT_AA string2
file2.txt
dn_id101_400_XX_XX diffstring1
dn_id400_40_XY_YX diffstring2
dn_id111_60_GG_CC diffstring3
如果在file2.txt中的行中存在由_
与file1.txt分隔的前三个元素,我想从file2.txt打印行。这是我想要的输出:
dn_id101_400_XX_XX diffstring1
dn_id111_60_GG_CC diffstring3
有办法做到这一点吗?也许通过更改awk
的分隔符?我不确定如何在awk
命令中处理多个分隔符。以下是我想要使用的示例:
awk -F"\t" 'FNR==NR {a[$1]; next}; $1 in a' file1.txt file2.txt
答案 0 :(得分:2)
使用cut
,paste
,join
,sort
和函数定义来替代awk
功能的替代解决方案
$ f() { paste <(cut -d_ -f1-3 ${1}) ${1} | sort; }; \
join -o2.2,2.3 <(f file1) <(f file2)
dn_id101_400_XX_XX diffstring1
dn_id111_60_GG_CC diffstring3
为连接创建键和排序,选择要输出的列,定义函数用于消除重复的代码。
答案 1 :(得分:2)
您只需要:
$ awk -F_ '{k=$1 FS $2 FS $3} NR==FNR{a[k];next} k in a' file1 file2
dn_id101_400_XX_XX diffstring1
dn_id111_60_GG_CC diffstring3
答案 2 :(得分:1)
你可以这样做:
$ awk -F"\t" '
{s=$1; sub(/_[[:upper:]]+_[[:upper:]]+$/, "", s)}
FNR==NR { arr[s]++}
FNR<NR && (s in arr)' f1 f2
dn_id101_400_XX_XX diffstring1
dn_id111_60_GG_CC diffstring3
假设/_[[:upper:]]+_[[:upper:]]+$/
正确描述了您需要删除的部分,以使数据键在两个文件之间重叠。
如果你想从左到右(不论前三个之后_
的数量),请使用split
代替:
$ awk -F"\t" '
{ split($1, a, /_/); s=a[1]"_"a[2]"_"a[3]}
FNR==NR { arr[s]++}
FNR<NR && (s in arr)' f1 f2
答案 3 :(得分:1)
我的方法是拔出&#34;键&#34;您希望从file1获得的值。
awk -F_ '
NR==FNR{str="^"$1"_"$2"_"$3; arr[str]=str}
NR!=FNR{for (x in arr){if ($0 ~ x) {print $0 ; next }}}
#END{for(x in arr) print "arr["x"]="arr[x]}
' f1.txt f2.txt
<强>输出强>
dn_id101_400_XX_XX diffstring1
dn_id111_60_GG_CC diffstring3
这会将file1中的前3个_
分隔值重建为$1"_"$2"_"$3
。
删除#
注释字符以查看arr[]
中存储的值。
NR==FNR
和NR!=FNR
控制将哪个文件读入arr[]
,并将其处理为与($0 ~ str)
匹配。
IHTH