GNU/Linux >> Tutoriales Linux >  >> Linux

¿Insertar nuevas líneas con valores faltantes (na)?

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.

Relacionado:¿Tiempo de espera agotado en un script de shell?
Linux
  1. ¿Qué hay de nuevo con rdiff-copia de seguridad?

  2. Enumerar una nueva red con Nmap

  3. Con el comando "cat" de Linux, ¿cómo mostrar solo ciertas líneas por número?

  4. ¿Eliminar líneas consecutivas en Csv con valores duplicados en un campo, pero conservar la última línea?

  5. ¿Duplicar, con unos pequeños cambios, unas pocas líneas en un archivo de texto?

Cómo eliminar una línea en Vim en Linux

Tutorial de Unix Sed:anexar, insertar, reemplazar y contar líneas de archivos

¿Cómo insertar una nueva línea en el correo electrónico usando el comando de correo de Linux?

línea de inserción sed con espacios a una línea específica

¿Cómo insertar una nueva línea en el script de shell de Linux?

reemplazar líneas en un archivo con líneas en otro por número de línea