打印具有类似列和多个分隔符的行

时间:2016-03-07 23:43:37

标签: awk text-processing

我有两个文件:

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

4 个答案:

答案 0 :(得分:2)

使用cutpastejoinsort和函数定义来替代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==FNRNR!=FNR控制将哪个文件读入arr[],并将其处理为与($0 ~ str)匹配。

IHTH