file1、file2、file3、file4の4つのファイルがあります。各ファイルには、タブで区切られた2つの異なる列があります。 file1の最初の列(参照用)を2番目のファイルの最初の列、3番目、4番目のファイルと一致させ、一致する最初の列と各ファイルの一致する最初の列を2番目の列に印刷したいと思います。ファイルは次のとおりです。
ファイル1
Bm1_00085|Bm1_22625 0.263974289
Bm1_00087|Bm1_22620 0.663443490
ファイル2
Bm1_00085|Bm1_22625 0
Bm1_57630|Bm1_52870 0
ファイル3
Bm1_57630|Bm1_54855 0
Bm1_00085|Bm1_22625 4
ファイル4
Bm1_57630|Bm1_52870 0
Bm1_00085|Bm1_22625 1
出力:
Bm1_00085|Bm1_22625 0.263974289 0 4 1
答え1
join
次の処理方法がわかるほどスマートなシェルを使用してください<(...)
。
join <(sort file1) <(sort file2) | join - <(sort file3) | join - <(sort file4)
出力:
Bm1_00085|Bm1_22625 0.263974289 0 4 1
答え2
awkを使用してこれを行う1つの方法は次のとおりです。
解析.awk
# Use the first column of the first file as a key and the second column
# as a value in the h hash
NR==FNR { h[$1] = $2; next }
# If $1 is a key in h append $2 to h[$1]
$1 in h { h[$1] = h[$1] OFS $2 }
# When the input has been exhausted, print h key value pairs
# that contain more than one element
END { for(k in h)
if(split(h[k], a) > 1)
print k OFS h[k]
}
次のように実行します。
awk -f parse.awk file1 file2 file3 file4
出力:
Bm1_00085|Bm1_22625 0.263974289 0 4 1
答え3
Perlでは、これを行うツールはハッシュです。ハッシュは一連のキーと値のペアであるため、相互参照は非常に簡単です。
注 - このようになりますただ最初のフィールドが一意の場合に機能します。
#!/usr/bin/env perl
use strict;
use warnings;
my %data;
while (<>) {
my ( $key, $value ) = split;
push( @{ $data{$key} }, $value );
}
foreach my $key ( sort keys %data ) {
if ( @{ $data{$key} } >= @ARGV ) {
print join( "\t", $key, @{ $data{$key} } ), "\n";
}
}
として呼び出されますmyscript.pl file1 file2 file3 file4
。
それ:
- コマンドラインからファイルのリストを読み取り、
<>
処理のために開きます。 - 一度に1行ずつ繰り返して、行を
$key
合計に分割します$value
。 $value
配列のハッシュに保存されます。ハッシュの各キーを繰り返します。
- 要素の数> =コマンドライン引数の数(ファイルの数など)の場合 - 行を印刷します。
出力は次のとおりです
Bm1_00085|Bm1_22625 0.263974289 0 4 1
メモ:
すべてのファイルに独自の「キー」があるとします。