Problema al extraer datos de un archivo usando awk

Problema al extraer datos de un archivo usando awk

Tengo un archivo de datos grande y quiero dividirlo en archivos más pequeños según los valores de la columna 1. Por ejemplo, la columna 1 tiene números del 1 al 10 diez veces para formar 100 filas y quiero que todas las líneas tengan los números '1' o '2 ' o '3', etc. en su propio archivo (preferiblemente sin ordenar). Además, no quiero ejecutar el comando 10 veces, por lo que me gustaría que estuviera en un bucle.

Mis archivos se ven así:

  • text.txt

    ingrese la descripción de la imagen aquí

  • ID.txt

    1
    2
    3
    4
    

El comando que probé:

cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done

Entonces, para resumir, quiero que lea el valor del archivo ID.txt, por ejemplo, '1' y luego extraiga todas las filas con '1' en la primera línea y lo coloque en un archivo llamado 1.txt, luego se itera a 2 y luego 3 luego 4 etc

Pero de alguna manera creo que la parte '$1 == ${line}' no funciona

Respuesta1

Estás buscando la -vopción de awk:

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

Algo como esto:

cat ID.txt | 
    while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done

Lo cual se expresaría mejor como (evitando el uso inútil de cat):

while read line; do 
    awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt

Sin embargo, esto es muy lento e ineficiente. Está ejecutando el awkcomando en su totalidad test.txtpara cada línea de ID.txt. ¿Por qué no simplemente leerlo ID.txte awkimprimir las líneas correspondientes?

awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt 

Lo anterior guarda el primer campo de ID.txtla matriz a. NRy FNRson awkvariables especiales que significan "la línea actual del flujo de entrada" y "la línea actual del archivo actual". Los dos sólo serán iguales entre sí cuando se lea el primer archivo. Por lo tanto, NR==FNR{a[$1]++; next}sólo se ejecutará en las líneas del primer archivo. La segunda parte no se ejecutará porque le nextindica awkque pase a la siguiente línea.

La segunda parte verifica si el primer campo de la línea actual (recuerde, esto solo se ejecuta en el segundo archivo) existe en la matriz a(lo que significa que estaba en ID.txt) y, si es así, imprime la línea en un archivo llamado "campo1. TXT"

información relacionada