¿Cómo ordenar por líneas impares y luego eliminar valores repetidos?

¿Cómo ordenar por líneas impares y luego eliminar valores repetidos?

Tengo el siguiente tipo de archivo:

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

Estaba intentando conseguir algo como esto:

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

Luego, después, estaba buscando algo como esto:

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

Revisé sortel manual y algunas publicaciones, pero no pude encontrar nada que se acerque a esto, solo sortuso valores numéricos para obtener líneas impares...

Respuesta1

gawkSolución pura :

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

El truco consiste en ordenar anuméricamente los índices de una matriz con un poco de ayuda de gawkla matriz especial PROCINFO.

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

Por cierto, es una pena que awk no ofrezca una opción para ordenar de forma natural, también conocido comoclasificación de versiones(según texto con números).

Respuesta2

No es exactamente el orden de clasificación que has mostrado, pero ¿tal vez también sea cierto?

$ 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 -

EDITAR:

Inserte el número de línea y utilícelo como clave de clasificación, debería producir el resultado exacto que desee:

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

Respuesta3

Con GNU sorty asumiendo que las líneas no contienen caracteres TAB:

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

O sort -t$'\t' -sk1,1Vpara preservar el orden original de las entradas con líneas impares idénticas como en el resultado esperado.

Si no tienes GNU sorty suponiendo que las líneas impares siempre sigan ese patrón, puedes reemplazarlo sort -Vcon sort -k1.9n.

Respuesta4

Preprocesamiento y posprocesamiento con awk; esto no supone que a una transcrlínea le siga solo una Y*línea; también es idempotente: su salida podría canalizarse como entrada y dará el mismo resultado.

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 -

información relacionada