Ich habe eine Textdatei mit Zeilen und Spalten innerhalb dieser Zeilen. Ich möchte im Wesentlichen die Excel-Funktion „Nach unten ausfüllen“ replizieren. Mit anderen Worten, wenn sich in einer Zeile eine leere „Zelle“ befindet, wird in die Zeile darüber geschaut und der Wert im entsprechenden Feld darüber nach unten ausgefüllt. Beispiel mit „^“ als Spaltentrennzeichen:
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
... wird zu (ausgefüllte Elemente zur besseren Übersicht in GROSSBUCHSTABEN):
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
Die Funktion besteht also im Wesentlichen darin, alle leeren Felder zu identifizieren und, sofern vorhanden, den Wert aus dem entsprechenden Feld darüber nach unten zu ziehen. Es ist wichtig, die Feld-/Spaltentrennzeichen angeben zu können. Irgendwelche Ideen?
Antwort1
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
}'
Dabei wird ein Array verwendet, das aufgerufen wird, save
um die Werte von einer Zeile zur nächsten zu speichern (nach unten ausfüllen). Alles darin awk
wird implizit auf null initialisiert, sodass das save
Array leer bleibt, bis ihm Daten zugewiesen werden. (Daher bleiben alle leeren Felder in der ersten Zeile leer, da keine vorherigen Daten vorhanden sind, die nach unten kopiert werden können.)
Für jede Zeile
- Für jedes Feld, das in dieser Zeile (
for (i = 1; i <= NF; i++)
) vorhanden ist,- Wenn es leer ist, füllen Sie es mit dem gespeicherten (kopierten) Wert für diese Spalte.
- andernfalls speichern Sie den aktuellen Wert für eine mögliche Verwendung in nachfolgenden Zeilen.
Löschen Sie dann das
save
Array für alle Spalten, die in der aktuellen Zeile nicht vorhanden sind. Wenn wir beispielsweise zu Zeile 4 gelangen (die nur vier Felder hat), „vergessen“ wir, dass die Spalten 5 und 6 von Zeile 3 „Singapur“ und „Neu-Delhi“ enthielten. Und wenn wir zu Zeile 7 gelangen (die nur ein Feld hat), „vergessen“ wir, dass Spalte 2 von Zeile 5 „Bangkok“ enthielt, sodass es nicht in Zeile 8 eingegeben werden kann (wo Spalte 2 leer ist).Ersetzen Sie
99
durch die größte Anzahl von Feldern, die Sie (jemals) in einer Zeile erwarten.