좋은 저녁이에요! 여러분의 도움이 필요합니다 :) 여기에 이 텍스트 파일이 있습니다
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-
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)
) 인 경우
세 가지 조건이 모두 true이면 해당
next
레코드로 점프하고, 그렇지 않으면 현재 레코드를 배열에 추가합니다. 블록의 배열 요소를 인쇄합니다end
.- 종명이 같은 경우 (
sort
: 원래 줄 번호에 따르면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.*
고유한 일치 항목 만 반환됩니다 .