Ich habe eine riesige Datei (mehr als 2 GB), in der die Daten wie folgt sind.
12,324,32342,E:fsdsf,23432,34534,45345,324
13,3224,342,E:werwefsdsf,23432,34534,45345,324
121,3244,33442,E:,23432,34534,45345,324
Hier muss ich alle Vorkommen der 4. Spalte ersetzen, wo immer sie auf E:
ein Leerzeichen stößt ""
, aber wo immer sie danach eine Zeichenfolge E:
findet, sollte diese so bleiben, wie sie ist.
Die erwartete Ausgabe wäre:
12,324,32342,E:fsdsf,23432,34534,45345,324
13,3224,342,E:werwefsdsf,23432,34534,45345,324
121,3244,33442,,23432,34534,45345,324
Antworten:
Ihre Syntax ist fast richtig.
awk
Verwenden Sie zum Testen der Zeichenfolgengleichheit ein doppeltes Gleichheitszeichen :==
. Verwenden Sie zum Zuweisen eines Werts ein einzelnes Gleichheitszeichen.Verwenden
if ($4 == "E:")
Sie also und Sie sollten das gewünschte Ergebnis erhalten.Der vollständige Befehl würde so aussehen. Beachten Sie, dass es nur einen Zeichenunterschied zu dem von Ihnen verwendeten Befehl gibt. das war dein einziger Fehler:
Um einige unterschiedliche Syntax und Ansätze zu zeigen, sind die folgenden Versionen genau gleichwertig:
Anmerkungen zu den oben genannten Punkten:
$4 == "E:" {$4 = ""}
ist genau gleichbedeutend mit{if ($4 == "E:") {$4 = ""}}
if ($4 == "E:") {$4 = ""}
nichtif ($4 == "E:") $4 = "";
-F
Legt den Wert von festFS
und-v
kann verwendet werden, um den Wert einer Variablen festzulegen, bevorawk
die erste Zeile der ersten Datei berücksichtigt wird. (Das wussten Sie wahrscheinlich.) Sie können auch einenBEGIN
Block verwenden, um dasselbe zu tun. Es lohnt sich zu wissen, wann Sie dasawk
Skript eigenständig machen möchten .1
Zeilen gedruckt werden,awk
besteht darin, dass es sich um eine Bedingung (einen Filter) handelt, die immer als wahr ausgewertet wird, und die Standardaktion,awk
wenn kein Codeblock an den Filter angehängt ist, lautetprint $0
. Also1
an sich ist gleichbedeutend mit1 {print}
oder1 {print $0}
oder nur{print}
.sub
Funktion verwendet, um den regulären Ausdruck/^E:$/
(Anfang der ZeichenfolgeE:
, Ende der Zeichenfolge) durch""
in zu ersetzen$4
.Da die
sub
Funktion die Anzahl der vorgenommenen Ersetzungen zurückgibt (entweder 1 oder 0; verwenden Siegsub
, um mehr als eine Ersetzung vorzunehmen), können Sie dieses Problem codieren, indem Sie demsub
Funktionsergebnis eine hinzufügen, um sicherzustellen, dass Sie ein Muster haben, das immer wahr ist dass die resultierende Zeile gedruckt wird, unabhängig davon, ob eine Ersetzung vorgenommen wurde oder nicht. Hier ist die Code-Golf-Version, die für Anfänger nicht empfohlen wird, wenn Sie diese in ein Skript einfügen, das Sie dann pflegen::) :)
quelle
Mit
sed
:Das durch Kommas getrennte 4. Feld wird leer gelassen, wenn es nur enthält
E:
.Beispiel:
quelle
Angenommen, Ihr Dateiname lautet
file
, können Sie Folgendes versuchen:oder:
Erläuterung:
while read -r line;
liest die Datei Zeile für Zeilevar="$(echo "$line" | cut -d ',' -f 4)";
Wunden die Zeichenfolge an 4. Stelle durch,
Variable getrenntvar
if [[ && "$var" = "E:" ]]; then echo "$line" | sed s/"$var"/' '/g ;
Wenn$var
genau eine Zeichenfolge vorhanden ist,E:
wirdsed s/"$var"/''/g ;
diese durch eine leere Zeichenfolge ersetzt""
else echo "$line";
Andernfalls wird die Linie so gedruckt, wie sie istBeispiel Ausgabe (ab Frage erwartet):
file
::Ausführender Befehl:
Sie können Ihre Ausgabe auch mit
>> file2
oder|tee file2
am letzten Befehl in eine Datei umleiten :quelle