他の行に似ていますが、短い行を削除する方法は?

他の行に似ていますが、短い行を削除する方法は?

おやすみなさい!あなたの助けが必要です:)ここにこのテキストファイルがあります

Espece_A ACGT
Espece_B ACCT
Espece_B GACCTT
Espece_B ATCTGG
Espece_C ACCTG
Espece_D ACCT

各行には、種名(Espece_X)と対応するシーケンス(AACGTなど)がスペースで区切られて含まれています。行は最初の単語に基づいてソートされます。

私の目標は他の行と似ていますが、短い行を削除することです。私は何をすべきかわかりません!

この例では、2番目の行は3番目の行とまったく同じですが、より短いので削除する必要があります。

結果ファイル:

Espece_A ACGT
Espece_B GACCTT
Espece_B ATCTGG
Espece_C ACCTG
Espece_D ACCT

よろしくお願いします。 Adrian

答え1

2xawk合計を使用するsortcut

awk '{print length($2), NR, $0}' file |
  sort -k1,1nr |
  awk '
  {
    for(i=1;i<=cnt;i++){
      split(lines[i], tmp)
      if ($3 == tmp[3] && $1 < tmp[1] && index(tmp[4], $4)) next
    }
    lines[++cnt]=$0
  }
  END{
    for(i=1;i<=cnt;i++) print lines[i]
  }' |
  sort -k2,2n |
  cut -d' ' -f3-
  1. awk:シーケンスフィールドの長さ、行番号、元の行を印刷します。

  2. sort:シーケンスフィールドの長さに応じて逆順に並べ替えると、次のようになります。

    6 3 Espece_B GACCTT
    6 4 Espece_B ATCTGG
    5 5 Espece_C ACCTG
    4 1 Espece_A ACGT
    4 2 Espece_B ACCT
    4 6 Espece_D ACCT
    
  3. awk:削除しないレコードを配列に追加しますlines。各レコードに対して追加された配列項目を繰り返しテストします。

    • 種名が同じ場合($3 == tmp[3]
    • シーケンスが短い場合($1 < tmp[1]
    • シーケンスが部分文字列(index(tmp[4], $4))の場合

    3つの条件がすべてtrueの場合はそのnextレコードにジャンプし、そうでない場合は現在のレコードを配列に追加します。ブロックの配列要素を印刷しますend

  4. sort:元の行番号によると

  5. cut: 最初の 2 つのフィールドを削除

答え2

短いPythonプログラムはこれを行い、Bashで簡単に実行できます。

#!/usr/bin/env python3
import sys
last_line = ""
for line in sys.stdin:
    if len(line) > len(last_line) or line[0:-1] != last_line[0:len(line)-1]:
        print(line, end='')
    last_line = line

使用法:

  • 上記のコードを次のファイルにコピーします。del_shorter.py
  • ファイルを実行可能にします。chmod +x del_shorter.py
  • 逆ソートされたファイルを入力として使用し、出力を並べ替えます。
cat your_file.txt |sort -r |./del_short_matches.py |sort

答え3

ファイルが大きすぎない場合は、ここに大きなハンマーがあります。

while read s g; 
   do n=$(sed -nE "/"$s" .*"$g".*/p" file | wc -l); 
  [ $n -eq 1 ] && echo $s $g;  
done < file 

species .*gene.*一意の一致のみが返されます。

関連情報