홀수 행을 기준으로 정렬한 다음 중복 값을 제거하는 방법은 무엇입니까?

홀수 행을 기준으로 정렬한 다음 중복 값을 제거하는 방법은 무엇입니까?

다음과 같은 유형의 파일이 있습니다.

transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_20649 +
YBL100C -
transcr_7135 +
YBL029C-A -
transcr_11317 +
YBL067C -
transcr_25793 +
YAL038W +
transcr_7135 +
YBL029W +

나는 다음과 같은 것을 얻으려고 노력하고 있습니다.

transcr_7135 +
YBL029C-A -
transcr_7135 +
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_25793 +
YAL038W +

그러다가 나중에 다음과 같은 것을 찾고 있었습니다.

transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
YAL037C-B -
YAL038W +

sort매뉴얼과 일부 게시물을 살펴봤지만 이에 적합한 것을 찾을 수 없으며 sort숫자 값을 사용하여 홀수 행을 얻습니다...

답변1

순수 gawk솔루션:

awk -F_ 'NR%2{i=$2;next}{a[i]=a[i]"\n"$0}
         END{PROCINFO["sorted_in"]="@ind_num_asc";
             for(i in a) printf "%s","transcr_"i""a[i]"\n"}' file

비결은 aPROCINFO 특수 배열의 약간의 도움을 받아 배열의 인덱스를 숫자로 정렬하는 것입니다.gawk

transcr_7135
YBL029C-A -
YBL029W +
transcr_11317
YBL067C -
transcr_20649
YBL100C -
transcr_25793
YAL039C -
YAL037C-B -
YAL038W +

그런데 안타깝게도 awk는 자연 정렬 옵션을 제공하지 않습니다.버전 정렬(숫자가 포함된 텍스트 기준)

답변2

보여주신 정렬 순서와 정확히 일치하지는 않지만 어쩌면 그것도 맞을까요?

$ cat input.txt|paste - -| sort -k1,1V -k2,2| tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'
    transcr_7135 +
    YBL029C-A -
    YBL029W +
    transcr_11317 +
    YBL067C -
    transcr_20649 +
    YBL100C -
    transcr_25793 +
    YAL037C-B -
    YAL038W +
    YAL039C -

편집하다:

행 번호를 삽입하고 이를 정렬 키로 사용하면 원하는 정확한 출력이 생성됩니다.

$ cat input.txt | paste - - | nl | sort -k2,2V -k1,1g | cut -f2- | tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'

답변3

GNU를 사용 sort하고 다음 줄에 TAB 문자가 포함되어 있지 않다고 가정합니다.

paste - - < file | sort -V | tr '\t' '\n' | awk '!seen[$0]++'

또는 sort -t$'\t' -sk1,1V예상 출력과 같이 홀수 행이 동일한 항목의 원래 순서를 유지하세요.

GNU가 없고 sort홀수 줄이 항상 이 패턴을 따른다고 가정한다면 sort -V로 바꿀 수 있습니다 sort -k1.9n.

답변4

사전 및 사후 처리 : 이는 행 뒤에 행이 따른다고 awk가정하지 않습니다 . 또한 멱등적입니다. 해당 출력은 입력으로 반환될 수 있으며 동일한 결과를 제공합니다.transcrY*

awk '{print $0~/^transcr/ ? t=$0 : t" "$0}' /tmp/foo | sort -t_ -k2n -k2 -u | awk '{print (NF > 2) ? $3" "$4 : $0}'
transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL037C-B -
YAL038W +
YAL039C -

관련 정보