Estoy tratando de reorganizar file1 que se ha ordenado por la última columna como se muestra a continuación

MEL P 20190731 0453 30.599
PUS P 20190731 0453 30.612
MEA P 20190731 0453 30.620
KDT P 20190731 0453 30.639
PAS P 20190731 0453 30.644
BDT P 20190731 0453 30.900
LAB P 20190731 0453 31.046
KLS P 20190731 0453 31.129
MEL S 20190731 0453 31.222
KDT S 20190731 0453 31.249
PAS S 20190731 0453 31.255
MEA S 20190731 0453 31.258
GRA P 20190731 0453 31.263
BDT S 20190731 0453 31.551
LAB S 20190731 0453 31.630
GRA S 20190731 0453 31.816

En output que quiero donde cada línea que contiene la misma cadena en la primera columna se agrupen una junto a la otra a lo largo de líneas, como

MEL P 20190731 0453 30.599
MEL S 20190731 0453 31.222
PUS P 20190731 0453 30.612
MEA P 20190731 0453 30.620
MEA S 20190731 0453 31.258
KDT P 20190731 0453 30.639
KDT S 20190731 0453 31.249
PAS P 20190731 0453 30.644
PAS S 20190731 0453 31.255
BDT P 20190731 0453 30.900
BDT S 20190731 0453 31.551
LAB P 20190731 0453 31.046
LAB S 20190731 0453 31.630
KLS P 20190731 0453 31.129
GRA P 20190731 0453 31.263
GRA S 20190731 0453 31.816

Sin dejar de respetar el orden de la última columna (observe que, por ejemplo, MEL ahora están uno al lado del otro y que la ubicación de PUS no cambia en relación con los demás).

He intentado este código para producir un key

awk '!array[$1]++ {print $1}' file1 > key

Donde intenté hacer coincidirlo con file1 para poder reordenar las líneas usando

grep -Fwf key file > output

Pero nada cambia. ¡Por favor ayuda!

0
dex10 16 may. 2020 a las 22:28

3 respuestas

La mejor respuesta

En awk:

$ awk '{
    if(!($1 in a))           # enumerate all unique $1 for looping in END
        n[++c]=$1
    a[$1]=a[$1] $0 ORS       # append records to hash keyed on $1
}
END {                        # after processing records
    for(i=1;i<=c;i++)        # loop 
        printf "%s",a[n[i]]  # and output
}' file

Salida:

MEL P 20190731 0453 30.599
MEL S 20190731 0453 31.222
PUS P 20190731 0453 30.612
MEA P 20190731 0453 30.620
MEA S 20190731 0453 31.258
KDT P 20190731 0453 30.639
KDT S 20190731 0453 31.249
PAS P 20190731 0453 30.644
PAS S 20190731 0453 31.255
BDT P 20190731 0453 30.900
BDT S 20190731 0453 31.551
LAB P 20190731 0453 31.046
LAB S 20190731 0453 31.630
KLS P 20190731 0453 31.129
GRA P 20190731 0453 31.263
GRA S 20190731 0453 31.816

Espera que los datos se ordenen en el último campo.

2
James Brown 16 may. 2020 a las 20:16

Con GNU ordenar por -s:

$ awk '!($1 in a){a[$1]=NR} {print a[$1], $0}' file | sort -s -k1,1n | cut -d' ' -f2-
MEL P 20190731 0453 30.599
MEL S 20190731 0453 31.222
PUS P 20190731 0453 30.612
MEA P 20190731 0453 30.620
MEA S 20190731 0453 31.258
KDT P 20190731 0453 30.639
KDT S 20190731 0453 31.249
PAS P 20190731 0453 30.644
PAS S 20190731 0453 31.255
BDT P 20190731 0453 30.900
BDT S 20190731 0453 31.551
LAB P 20190731 0453 31.046
LAB S 20190731 0453 31.630
KLS P 20190731 0453 31.129
GRA P 20190731 0453 31.263
GRA S 20190731 0453 31.816

Con cualquier tipo:

$ awk '!($1 in a){a[$1]=NR} {print a[$1], NR, $0}' file | sort -k1,1n -k2,2n | cut -d' ' -f3-
MEL P 20190731 0453 30.599
MEL S 20190731 0453 31.222
PUS P 20190731 0453 30.612
MEA P 20190731 0453 30.620
MEA S 20190731 0453 31.258
KDT P 20190731 0453 30.639
KDT S 20190731 0453 31.249
PAS P 20190731 0453 30.644
PAS S 20190731 0453 31.255
BDT P 20190731 0453 30.900
BDT S 20190731 0453 31.551
LAB P 20190731 0453 31.046
LAB S 20190731 0453 31.630
KLS P 20190731 0453 31.129
GRA P 20190731 0453 31.263
GRA S 20190731 0453 31.816
1
Ed Morton 16 may. 2020 a las 20:23

Creo que está buscando un "tipo estable" [0]. algo como:

 sort -s -k5,5n -k1,1 file1 > output

(o tal vez las teclas -k al revés)

https://en.wikipedia.org/wiki/Sorting_algorithm#Stability

Desde la página man

       -s, --stable
              stabilize sort by disabling last-resort comparison

0
tomc 16 may. 2020 a las 20:02