ordenar el archivo B según la columna 3 del archivo A sin cambiar el contenido del archivo A

ordenar el archivo B según la columna 3 del archivo A sin cambiar el contenido del archivo A

Tengo el siguiente archivo:

cat fileA.txt

seattle    1991  west
atlanta    1993  west
turlock    1998  west
marysville 2004  south
newyork    2007  north
canada     2004  west

Y el segundo archivo se ve así:

cat fileB.txt

popular
someWhatPopular
boring
popular
popular
popular

Me gustaría obtener el siguiente resultado sobre fileB.txt:

popular popular popular someWhatPopular boring popular

Básicamente, estoy intentando ordenar fileB.txten fileA.txtla tercera columna.

Probé el siguiente código:

   #!/bin/bash
   sort -s -k3,3 fileA.txt fileB.txt

Pero no funcionó. ¿Alguna sugerencia? Estoy bastante abierto a cualquier cosa que no requiera codificación. bash/awk/sed,etc.

Respuesta1

Este es un problema de estructura de datos más que de Linux. Necesita una entrada común (clave) en ambas tablas para vincularlas, igual que en cualquier 'base de datos' y es una buena práctica mantener una clave única en la primera columna de cualquier tabla de datos. Luego puedes ordenar y vincular el contenido de tu corazón.

Tomando algo como el mapeo @glennjackman, defines la clave de mapeo como norte, sur, etc.

1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored

en un archivo llamado archivo popularity. Modificar fileApara incluir una clave única

1 seattle    1991  west
2 atlanta    1993  west
3 turlock    1998  west
4 marysville 2004  south
5 newyork    2007  north
6 canada     2004  west

luego puede manipular estos archivos ingresándolos joinen la clave seleccionada (en su caso, la columna 2 en popularityse asigna a la columna 4 en fileA) pero join necesita que ambos archivos estén ordenados en el campo clave, por lo que

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'

popular
popular
popular
somewhatPopular
boring
popular

Un enfoque un poco duro, pero le brinda mayor flexibilidad.

Rompe el comando anterior en cada tubería y verás lo que hace cada paso.

Editar: Explicación dejoin -1 4 -2 2 # its in the man pages

Esto le indica joinque mire la cuarta columna de la tabla 1 (-1 4) y encuentre valores coincidentes en la segunda columna de la tabla 2 (-2 2).

joinluego compone columnas de las dos tablas en una sola tabla pero solo incluye la columna clave (norte, etc.) una vez. Mire la salida de

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)

y debería ser más claro

Debido a que tuvimos que ordenar las tablas de datos para que joinfuncionara, luego

| sort -k2

la tabla combinada para volver a colocarlos en su orden original.

La columna que desea es la columna 6 en la tabla combinada, por lo que simplemente

| awk '{print $6}'

a la salida estándar.

Respuesta2

Puede intentar pastejuntar los dos archivos de "tabla", canalizar la salida a sorty luego cutconservar solo la cuarta columna.

Un intento no probado (teléfono celular en este momento) sería algo así como

paste fileA fileB | sort -s -k3,3 | cut -f4

Respuesta3

Puede obtener el mapeo alfabético con

paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north   boring
south   popular
west    someWhatPopular

Y luego se puede producir una forma del resultado deseado con awk:

awk '
    NR==FNR {map[$1] = $2; next} 
    {print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular

información relacionada