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 awk
se inicializa implícitamente a nulo, por lo que la save
matriz 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
save
matriz 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 la
99
con la mayor cantidad de campos que espera ver en una fila (nunca).