Comando para "rellenar" columnas en un archivo de texto, al estilo de la función de relleno de Excel

Comando para "rellenar" columnas en un archivo de texto, al estilo de la función de relleno de Excel

Tengo un archivo de texto con filas y columnas dentro de esas filas. Básicamente, quiero replicar la función de "completar" de Excel. En otras palabras, si hay una "celda" en blanco en una línea, buscará la línea encima de ella y completará el valor en el campo correspondiente encima de ella. Ejemplo, utilizando "^" como separador de columnas:

London^Paris^Moscow^Berlin
^^Melbourne^New York^Washington
^^^Sydney^Singapore^New Delhi
^^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
^^^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
^^Bucharest

... se convierte en (elementos completados en MAYÚSCULAS para mayor claridad):

London^Paris^Moscow^Berlin
LONDON^PARIS^Melbourne^New York^Washington
LONDON^PARIS^MMELBOURNE^Sydney^Singapore^New Delhi
LONDON^PARIS^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
KUALA LUMPUR^BANGKOK^HONG KONG^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
AMSTERDAM^^Bucharest

Básicamente, la función es identificar cualquier campo en blanco y, cuando lo haya, bajar el valor del campo correspondiente que se encuentra encima. Importante poder especificar los separadores de campo/columna. Algunas ideas ?

Respuesta1

awk -F'^' -v OFS='^' \
   '{
        for (i = 1; i <= NF; i++) {
                if ($i == "") $i = save[i]
                else          save[i] = $i
        }
        for (i = NF+1; i <= 99; i++) save[i] = ""
        print
    }'

Esto utiliza una matriz llamada save para guardar los valores de una línea a la siguiente (llenando hacia abajo). Todo lo que contiene awkse inicializa implícitamente a nulo, por lo que la savematriz estará en blanco hasta que se le asignen datos. (Por lo tanto, cualquier campo en blanco en la primera fila se dejará en blanco porque no hay datos anteriores para copiar en ellos).

Para cada línea,

  • Para cada campo que existe en esta línea ( for (i = 1; i <= NF; i++)),
    • si está en blanco, rellénelo con el valor guardado (copiado) para esta columna,
    • de lo contrario, guarde el valor actual para su posible uso en líneas posteriores.
  • Luego borre la savematriz de todas las columnas que no estén presentes en la línea actual. Por ejemplo, cuando llegamos a la fila 4 (que tiene sólo cuatro campos), "olvidamos" que las columnas 5 y 6 de la fila 3 contenían "Singapur" y "Nueva Delhi". Y cuando llegamos a la fila 7 (que tiene solo un campo), "olvidamos" que la columna 2 de la fila 5 contenía "Bangkok", por lo que no está disponible para ingresarlo en la fila 8 (donde la columna 2 está en blanco).

    Reemplace la99 con la mayor cantidad de campos que espera ver en una fila (nunca).

información relacionada