
おやすみなさい!あなたの助けが必要です:)ここにこのテキストファイルがあります
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
合計を使用するsort
:cut
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-
awk
:シーケンスフィールドの長さ、行番号、元の行を印刷します。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
awk
:削除しないレコードを配列に追加しますlines
。各レコードに対して追加された配列項目を繰り返しテストします。- 種名が同じ場合(
$3 == tmp[3]
) - シーケンスが短い場合(
$1 < tmp[1]
) - シーケンスが部分文字列(
index(tmp[4], $4)
)の場合
3つの条件がすべてtrueの場合はその
next
レコードにジャンプし、そうでない場合は現在のレコードを配列に追加します。ブロックの配列要素を印刷しますend
。- 種名が同じ場合(
sort
:元の行番号によると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.*
一意の一致のみが返されます。