Das Löschen von Feldern in awk ist bekanntermaßen schwierig. Es scheint eine so einfache (und oft erforderliche) Operation zu sein, aber es ist schwieriger als es sein sollte.
Siehe Gibt es eine Möglichkeit, Felder in awk vollständig zu löschen, damit keine zusätzlichen Trennzeichen gedruckt werden?
von Stack Overflow für einen guten Weg, dies zu tun.
Ich habe die rmcol()
Funktion in @ ghotis Antwort kopiert , so dass wir hier auf U & L eine Kopie haben:
function rmcol(col, i) {
for (i=col; i<NF; i++) {
$i=$(i+1)
}
NF--
}
Es löscht die angegebene Spalte aus der aktuellen Eingabezeile und dekrementiert den Feldzähler ( NF
) entsprechend.
Ich habe keine Ahnung, was Ihre transform()
Funktion tut, daher werde ich nicht einmal versuchen, dies zu duplizieren - aber hier ist ein Beispiel für die Verwendung rmcol()
in einem awk
Einzeiler:
$ echo 'field1,field2,field3' | awk -F, -v OFS=, '
function rmcol(col, i) {
for (i=col; i<NF; i++) {
$i=$(i+1)
}
NF--
}
{ rmcol(2); print; }
'
field1,field3
Übrigens, wenn Sie mehrere Felder aus einer Eingabezeile löschen müssen, ist es am besten / einfachsten, sie in umgekehrter Reihenfolge zu löschen. Das heißt, löschen Sie die höchsten nummerierten Felder zuerst . Warum? Da die Felder mit der höheren Nummer jedes Mal neu nummeriert werden, wenn Sie ein Feld mit der niedrigeren Nummer löschen, ist es sehr schwierig zu verfolgen, welche Feldnummer zu welchem Feld gehört.
Übrigens dient delete()
in awk
zum Löschen von Elementen eines Arrays - nicht zum Löschen von Feldern aus einer Eingabezeile. Sie könnten split()
jede Eingabezeile (ein FS
) in ein Array eingeben und das zweite Array-Element löschen, aber dann müssten Sie eine join()
Funktion schreiben , um das Array mit einem Komma (oder OFS
) zu drucken, das jedes Feld trennt.
Selbst dies wäre komplizierter als erwartet, da alle Arrays in awk
assoziativen Arrays sind (dh nicht numerisch indiziert sind), sodass Array-Elemente 3+ delete(array[2])
nicht automatisch in Elemente 2+ verschoben werden. Sie müssten Ihre eigene Wrapper-Funktion herumschreiben, um delete()
für Arrays fast dasselbe zu tun rmcol()
wie für Eingabefelder.