2つのファイルを比較して一致させて1つのファイルに印刷したいと思います。

2つのファイルを比較して一致させて1つのファイルに印刷したいと思います。

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

joinsortおよび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
  1. sort ファイル1&ファイル2bashの*process置換を使用して...
  2. _フィールド区切り文字を使用すると、両方のファイルがjoinフィールド#2の共通インスタンスにソートされ、両方のファイルで一致しない行も個別に印刷されます。存在しないフィールド1.9999各結合ペアを追加フィールドに分割して、_手順3を簡素化します。
  3. 見苦しい出力をクリーンアップするために使用しますsed
  4. 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

関連情報