다른 행과 유사하지만 더 짧은 행을 삭제하는 방법은 무엇입니까?

다른 행과 유사하지만 더 짧은 행을 삭제하는 방법은 무엇입니까?

좋은 저녁이에요! 여러분의 도움이 필요합니다 :) 여기에 이 ​​텍스트 파일이 있습니다

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

각 줄에는 종 이름(Espece_X)과 해당 시퀀스(예: AACGT)가 공백으로 구분되어 포함됩니다. 줄은 첫 번째 단어를 기준으로 정렬됩니다.

내 목표는 다른 행과 유사하지만 더 짧은 행을 삭제하는 것입니다. 나는 무엇을 해야할지 모르겠습니다!

이 예에서는 두 번째 행이 세 번째 행과 정확히 동일하지만 더 짧기 때문에 삭제해야 합니다.

결과 파일:

Espece_A ACGT
Espece_B GACCTT
Espece_B ATCTGG
Espece_C ACCTG
Espece_D ACCT

미리 감사드립니다. Adrian

답변1

2x awk합계 사용 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-
  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)) 인 경우

    세 가지 조건이 모두 true이면 해당 next레코드로 점프하고, 그렇지 않으면 현재 레코드를 배열에 추가합니다. 블록의 배열 요소를 인쇄합니다 end.

  4. sort: 원래 줄 번호에 따르면

  5. cut: 처음 두 필드 삭제

답변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.*고유한 일치 항목 만 반환됩니다 .

관련 정보