![我想比较和匹配两个文件并将它们打印到一个文件中](https://linux22.com/image/96939/%E6%88%91%E6%83%B3%E6%AF%94%E8%BE%83%E5%92%8C%E5%8C%B9%E9%85%8D%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E5%B9%B6%E5%B0%86%E5%AE%83%E4%BB%AC%E6%89%93%E5%8D%B0%E5%88%B0%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD.png)
我有两个文件,file1 和 file2
文件1:
r11_abc_gkhsa 1.0 1.5 1.9
r11_bcd_gkhsa 1.0 1.5 1.7
r11_acd_gkhsa 1.3 1.6 1.5
r11_xyz_gkhsa 1.0 1.5 1.9
文件2:
sd1_bcd_gkhsa 1.8 1.5 1.9
ab1_abc_gkhsa 1.6 1.4 1.5
sfs_xyz_gkhsa 1.4 1.6 1.4
sd1_acd_gkhsa 1.2 1.3 1.5
sfs_ryb_gkhsa 1.5 1.2 1.7
我想将 file1 的“ abc 、 bcd 、 acd 和 xyz”与 file2 匹配。每当它与 file2 匹配时,我想按以下方式打印它。
输出:
r11_abc_gkhsa 1.0 1.5 1.9 ab1_abc_gkhsa 1.6 1.4 1.5
r11_bcd_gkhsa 1.0 1.5 1.7 sd1_bcd_gkhsa 1.8 1.5 1.9
r11_acd_gkhsa 1.3 1.6 1.5 sd1_acd_gkhsa 1.2 1.3 1.5
r11_xyz_gkhsa 1.0 1.5 1.9 sfs_xyz_gkhsa 1.4 1.6 1.4
sfs_ryb_gkhsa 1.5 1.2 1.7
可以使用 Perl 或 sed。有人可以给我一些想法来解决这个问题吗?
答案1
如果你只想使用普通bash
数组——
#read in the data from 2 files
unset arr1; declare -A arr1;
while read -r -u3 line; do \
i=${line%_*}; \
i=${i#*_}; \
arr1[$i]+=" $line"; \
done 3< <(cat f1 f2); \
exec 3<&-
#output array by iterating throug the keys
for k in "${!arr1[@]}"; do \
echo ${arr1[$k]}; \
done | sort
输出 -
r11_abc_gkhsa 1.0 1.5 1.9 ab1_abc_gkhsa 1.6 1.4 1.5
r11_acd_gkhsa 1.3 1.6 1.5 sd1_acd_gkhsa 1.2 1.3 1.5
r11_bcd_gkhsa 1.0 1.5 1.7 sd1_bcd_gkhsa 1.8 1.5 1.9
r11_xyz_gkhsa 1.0 1.5 1.9 sfs_xyz_gkhsa 1.4 1.6 1.4
sfs_ryb_gkhsa 1.5 1.2 1.7
答案2
使用join
、sort
和sed
:
join -j 2 -t_ -a 1 -a 2 -o 1.1,1.2,1.3,1.9999,2.1,2.2,2.3 \
<(sort -t_ -k2 file1) <(sort -t_ -k2 file2) | \
sed 's/__/ /g;s/^ *//g' | sort
sort
文件1&文件2使用bash
's *process 替换,然后...- 使用
_
字段分隔符,join
在字段 #2 的公共实例上排序两个文件,并且还单独打印任一文件中不匹配的任何行。不存在的字段1.9999
将每个连接对与一个额外的字段分开,_
以简化步骤 #3。 - 使用 清理丑陋的输出
sed
。 sort
结果。
输出:
r11_abc_gkhsa 1.0 1.5 1.9 ab1_abc_gkhsa 1.6 1.4 1.5
r11_acd_gkhsa 1.3 1.6 1.5 sd1_acd_gkhsa 1.2 1.3 1.5
r11_bcd_gkhsa 1.0 1.5 1.7 sd1_bcd_gkhsa 1.8 1.5 1.9
r11_xyz_gkhsa 1.0 1.5 1.9 sfs_xyz_gkhsa 1.4 1.6 1.4
sfs_ryb_gkhsa 1.5 1.2 1.7