Me gustaría insertar nuevas líneas en los archivos de texto si faltan valores.
Tengo, por ejemplo, el siguiente archivo de texto (A.txt), para el que falta la línea 5. Además, como el archivo debe tener 12 líneas, también faltan las líneas 11-12.
1 2.30
2 3.01
3 3.22
4 3.34
6 3.01
7 2.90
8 2.99
9 3.00
10 3.02
Mi resultado esperado es el siguiente. Para los casos que faltan, se debe agregar una línea con el número y NA. Como ves, esto sucedió como se desea en la línea 5, 11 y 12:
1 2.30
2 3.01
3 3.22
4 3.34
5 NA
6 3.01
7 2.90
8 2.99
9 3.00
10 3.02
11 NA
12 NA
Puedo hacer esto usando el siguiente script:
f1=/my-directory/
echo "new file" > "$f1"/newfile.txt
for i in {1..12}; do
l=$(awk '{print $1}' /"$f1"/A.txt | grep -wE ^$i /"$f1"/A.txt)
if grep --quiet -wE ^$i /"$f1"/A.txt; then echo "$l" >> "$f1"/newfile.txt; else echo "$i NA" >> "$f1"/newfile.txt; fi
done
Esto funciona bien. Sin embargo, el problema es que necesito hacer esto para unos 600 archivos que contienen más de 160000 líneas. Por lo tanto, la solución de bucle llevaría demasiado tiempo buscando en todas las líneas. Mi pregunta es:¿hay una solución más simple que pueda hacer esto?
Respuesta aceptada:
Puedes hacer esto con un awk
guión:
awk '{ while (NR + shift < $1) { print (NR + shift) " NA"; shift++ }; print } END { shift++; while (NR + shift < 13) { print (NR + shift) " NA"; shift++ } }' /tmp/test1
producirá la salida requerida para /tmp/test1
(reemplácelo con cada archivo que desee procesar).
En una forma más legible:
#!/usr/bin/awk -f
{
while (NR + shift < $1) {
print (NR + shift) " NA"
shift++
}
print
}
END {
shift++
while (NR + shift < 13) {
print (NR + shift) " NA"
shift++
}
}
Guarde esto como un archivo, diga fill-missing
, hazlo ejecutable, luego puedes simplemente ejecutar
./fill-missing /tmp/test1
El script procesa cada línea, haciendo un seguimiento del delta esperado con el número de línea actual en shift
. Entonces, para cada línea, si la línea actual ajustada no coincide con el primer número de la línea, imprime el número de línea apropiado seguido de NA
e incrementa el delta; una vez que los números de línea coinciden, imprime la línea actual. Al final del proceso, imprime las líneas faltantes requeridas para llegar a 12.