ubuntu - línea de comando - busca e imprime información específica con su nombre

CorePress2023-09-17  1

Tengo una lista del archivo de datos 1 que quiero encontrar en el archivo 2 donde quiero buscar el patrón de coincidencia con su nombre. No es necesario que cada nombre esté formado por datos únicos. Puede ser común entre los nombres.

Archivo 1:

123_A7
456_B2
789_f5
111_L2

archivo principal:

A   Edwin
B   777
B   123_A7
B   456_B2
A   Alex
B   453
B   678
A   Marwin
B   789
B   123_A7
B   111_L2
B   452

Resultado deseado:

B   123_A7
A   Edwin
A   Marwin
B   456_B2
A   Edwin
B   111_L2
A   Marwin
  • ¿Estás seguro de que la línea 5 de tu resultado no debería leer A Edwin? - Philippos 21 de septiembre de 2017 a las 10:29
  • @Philippos sí, lo he corregido. Gracias - Rea 21 de septiembre de 2017 a las 10:59
  • 1 ¿Puede aclarar cómo y por qué las líneas que contienen A Edwin y A Marwin deberían estar presentes en el resultado? - Wayne_Yux 21 de septiembre de 2017 a las 11:58
  • 1Su descripción de coincidencia de patrones no explica cómo los patrones en el archivo 1 coincidirían con Edwin o Marvin. ¿Podrías aclararlo? - David Foerster 21 de septiembre de 2017 a las 13:20
  • @Philippos Revertí tu edición ya que no sabemos si esto es así.Ese es realmente el razonamiento que pretendía el OP (aunque parece lógico y puede ser cierto) - Wayne_Yux 21 de septiembre de 2017 a las 14:43


------------Respuesta------------

Puedes usar sed:

sed '/\s/{H;d;}
  G;s/\nB/#B/g
  s/^\(.*\)\(\n\n.*#\)\(B\s*\)/#/
  /^[^#]*\n/d
  :a;s/^\([^#]*\)\(#.*\n\)\(A[^#]*\)\([^\n]*#\)/#/;ta
  s/#\n.*//;y/#/\n/' main file1

Primero lea el archivo principal para recopilar los códigos de cada nombre en el espacio de espera (línea 1). Luego, para cada línea del archivo 1, agregue el espacio de retención, reemplace las nuevas líneas antes de las líneas B con # para facilitar el análisis (línea 2) y busque con referencias anteriores códigos coincidentes (línea 3). Eliminar líneas sin coincidencias(línea 4). Ahora haga un bucle para recopilar los nombres del patrón dado (línea 5). Finalmente imprima con el espacio restante eliminado y # convertido nuevamente en nuevas líneas (línea 6). (Nota: funciona solo con GNU sed)


  • Muy impresionante, pero ¿no sería más sencillo con awk? -postre 21 de septiembre de 2017 a las 11:43
  • Dejé awk por perl hace mucho tiempo. Hoy en día hago tareas complejas en python y el resto en sed, no queda espacio para awk. Esta quizás sería más fácil de mantener en python. Pero puedes sugerir una versión de awk . - Philippos 21 de septiembre de 2017 a las 11:58


------------Respuesta------------

Usaría awk para esto:

awk 'NR==FNR{seen[];next} /^A/{NAME=
B   123_A7
A   Edwin
B   456_B2
A   Edwin
B   123_A7
A   Marwin
B   111_L2
A   Marwin
} {for (x in seen){ if (==x)print
awk -F'\t' '{a[]=a[]"\n"} END{for (i in a) print i""a[i]}' <(
    awk 'NR==FNR{seen[];next} 
        /^A/{NAME=
B   111_L2
A   Marwin
B   456_B2
A   Edwin
B   123_A7
A   Edwin
A   Marwin
}{for (x in seen){ if (==x)print 1008611"\t"NAME} }' file1 main)
"\n"NAME}}' file1 main

El resultado es:

1008611

Arriba está imprimiendo los ID y el nombre si hereda de ese ID, pero por separado. Aquí está el script completo para agrupar nombres queAquí tienen los mismos ID.

1008611

El resultado es:

1008611
  • @derHugo en este caso el resaltado de sintaxis es inútil, ya que todo el código awk está dentro de una cadena. -muru 15 de noviembre de 2017 a las 11:34