file1とfile2という2つのファイルがあります。
ファイル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&ファイル2bash
の*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