2017-02-17 5 views
3

私は、大きなタブが、このような多くの生化学的経路の座標を持つ2つの列区切りファイルがあります:awkを使用して共通フィールドに基づいてファイルの行をマージするにはどうすればよいですか?

A B 
B D 
D F 
F G 
G I 
A C 
C P 
P R 
A M 
M L 
L X 

1行の1列目は、結果として、別の行の列2に等しい場合、私はラインを組み合わせたいです次の出力で:

A B D F G I 
B D F G I 
D F G I 
F G I 
G I 
A C P R 
C P R 
P R 
A M L X 
M L X 
L X 

私は、誰もが、私はシェルスクリプトを記述することなく、これをアプローチする方法を任意のアイデアを持っていない、などのawk 1ライナーのような単純なものを使用したいですか?どんな助けもありがとうございます。私はそれぞれのステップとそれに続く各ステップを各パスウェイに入れようとしています。これらの経路はしばしば交差するので、いくつかのステップは他の経路と共有されますが、それぞれを別々に分析する必要があります。

私はそれ以降のファイルで$ 2 = $ 1目的の列をgrepをしようとするシェルスクリプト試してみました:私は私の問題は、(a)のラインを削除し、(Bから来ていることを知ってい

while [ -s test ]; do 
    grep -m1 "^" test > i 
    cut -f2 i | sed 's/^/"/' | sed 's/$/"/' | sed "s/^/awk \'\$1 == /" | sed "s/$/' test >> i/" > i.sh 
    sh i.sh 
    perl -p -e 's/\n/\t/g' i >> OUT 
    sed '1d' test > i ; mv i test 
done 

を)重複があるという事実。私はこれにどのように取り組むか分かりません。

+0

は、列2を選択し、値== 1列目が、私の問題は、それがgrepすることで、それぞれの行をgrepします(明らかに)すべての値を外して、信頼できる "地図"を作成しない – Oddish

+0

人々はあなたの試行を感謝し、自分自身を投稿して、(または)あなたの既存の試みを解決する際にあなたを導くように、質問の一部としてそれを更新してください。 – Inian

+0

その入力から出力がどのように生成されるかの例を説明できますか?それは(私には少なくとも)明確ではない – Inian

答えて

3

入力

$ cat f 
A B 
B D 
D F 
F G 
G I 
A C 
C P 
P R 
A M 
M L 
L X 

出力

$ awk '{ 
     for(j=1; j<=NF; j+=2) 
     { 
      for(i=j;i<=NF;i+=2) 
      { 
       printf("%s%s", i==j ? $i OFS : OFS,$(i+1)); 
       if($(i+1)!=$(i+2)){ print ""; break } 
      } 
      } 
     }' RS= OFS="\t" f 
A B D F G I 
B D F G I 
D F G I 
F G I 
G I 
A C P R 
C P R 
P R 
A M L X 
M L X 
L X 
私は、ファイル内の行を取るシェルスクリプトを書いて試してみました10

ワンライナー

awk '{ for(j=1; j<=NF; j+=2)for(i=j;i<=NF;i+=2){printf("%s%s", i==j ? $i OFS : OFS,$(i+1)); if($(i+1)!=$(i+2)){ print ""; break }}}' RS= OFS="\t" f 
+1

ニース、' ++値する 'のような出力を得ることができたとしても、あなたの入力行は、スペース区切りではなくタブが – Inian

0

さて、あなたは1行でこれを置くことができますが、私はそれをお勧めしません:)

#!/usr/bin/awk -f 

{ 
    a[NR] = $0 

    for(i = 1; i < NR; i++){ 
    if(a[i] ~ $1"$") 
     a[i] = a[i] FS $2 
    if(a[i] ~ "^"$1){ 
     for(j = i; j < NR; j++){ 
     print a[j] 
     delete a[j] 
     } 
    } 
    } 
} 

END{ 
    for(i = 1; i <= NR; i++) 
    if(a[i] != "") 
     print a[i] 
} 
0
$ <f.txt tac | awk 'BEGIN{OFS="\t"}{if($2==c1){$2=$2"\t"c2};print $1,$2;c1=$1;c2=$2}' | tac 
A  B  D  F  G  I 
B  D  F  G  I 
D  F  G  I 
F  G  I 
G  I 
A  C  P  R 
C  P  R 
P  R 
A  M  L  X 
M  L  X 
L  X 
関連する問題