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í:
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 -v
opció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 awk
comando en su totalidad test.txt
para cada línea de ID.txt
. ¿Por qué no simplemente leerlo ID.txt
e awk
imprimir 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.txt
la matriz a
. NR
y FNR
son awk
variables 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 next
indica awk
que 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"