홀수 줄로 정렬한 다음 반복되는 값을 제거하는 방법은 무엇입니까?

홀수 줄로 정렬한 다음 반복되는 값을 제거하는 방법은 무엇입니까?

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

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

비결은 의 PROCINFO 특수 배열을 a사용하여 배열의 인덱스를 숫자로 정렬하는 것입니다.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; 이는 한 transcr줄 뒤에 단 한 줄만 따른다고 가정하지 않습니다 Y*. 또한 멱등성입니다. 출력을 입력으로 다시 파이프할 수 있으며 동일한 결과를 제공합니다.

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 -

관련 정보