wake-up-neo.net

Schneiden Sie führende und nachfolgende Leerzeichen von einer Zeichenfolge in awk

Ich versuche, führenden und nachgestellten Leerzeichen in der zweiten Spalte des folgenden Codes zu entfernen input.txt:

Name, Order  
Trim, working
cat,cat1

Ich habe die nachstehende awk verwendet, um führenden und nachlaufenden Speicherplatz in der 2. Spalte zu entfernen, aber es funktioniert nicht. Was vermisse ich?

awk -F, '{$2=$2};1' input.txt

Dies gibt die Ausgabe als:

Name, Order  
Trim, working
cat,cat1

Führende und nachfolgende Leerzeichen werden nicht entfernt.

36
Marjer

Wenn Sie alle Leerzeichen abschneiden möchten, nur in Zeilen, die ein Komma enthalten, und awk verwenden, funktioniert Folgendes für Sie:

awk -F, '/,/{gsub(/ /, "", $0); print} ' input.txt

Wenn Sie nur Leerzeichen in der zweiten Spalte entfernen möchten, ändern Sie den Ausdruck in

awk -F, '/,/{gsub(/ /, "", $2); print$1","$2} ' input.txt

Beachten Sie, dass gsub das Zeichen in // durch den zweiten Ausdruck ersetzt, und zwar in der Variablen, die der dritte Parameter ist, und zwar in-place. Mit anderen Worten, wenn dies abgeschlossen ist, wurde $0 (oder $2) geändert.

Vollständige Erklärung:

-F,            use comma as field separator 
               (so the thing before the first comma is $1, etc)
/,/            operate only on lines with a comma 
               (this means empty lines are skipped)
gsub(a,b,c)    match the regular expression a, replace it with b, 
               and do all this with the contents of c
print$1","$2   print the contents of field 1, a comma, then field 2
input.txt      use input.txt as the source of lines to process

EDITIch möchte darauf hinweisen, dass die @ BMW-Lösung besser ist, da mit zwei aufeinanderfolgenden gsub-Befehlen eigentlich nur führende und nachgestellte Leerzeichen abgeschnitten werden. Während ich Kredit gebe, werde ich erklären, wie es funktioniert.

gsub(/^[ \t]+/,"",$2);    - starting at the beginning (^) replace all (+ = zero or more, greedy)
                             consecutive tabs and spaces with an empty string
gsub(/[ \t]+$/,"",$2)}    - do the same, but now for all space up to the end of string ($)
1                         - ="true". Shorthand for "use default action", which is print $0
                          - that is, print the entire (modified) line
55
Floris

entfernen Sie führende und nachfolgende Leerzeichen in der 2. Spalte

awk 'BEGIN{FS=OFS=","}{gsub(/^[ \t]+/,"",$2);gsub(/[ \t]+$/,"",$2)}1' input.txt

ein anderer weg von einem gsub:

awk 'BEGIN{FS=OFS=","} {gsub(/^[ \t]+|[ \t]+$/, "", $2)}1' infile
27
BMW

Ich würde sed verwenden:

sed 's/, /,/' input.txt

Dadurch wird der führende Platz nach dem , entfernt. Ausgabe:

Name,Order
Trim,working
cat,cat1

Allgemeiner kann Folgendes sein: Es werden möglicherweise mehrere Leerzeichen und/oder Registerkarten nach dem , entfernt:

sed 's/,[ \t]\?/,/g' input.txt

Aufgrund des globalen Modifizierers /g kann auch mit mehr als zwei Spalten gearbeitet werden.


@Floris hat in der Diskussion nach einer Lösung gefragt, mit der nach und nach Leerzeichen in jeder Spalte (auch in der ersten und letzten) entfernt werden, wobei keine Leerzeichen in der Mitte einer Spalte entfernt werden:

sed 's/[ \t]\?,[ \t]\?/,/g; s/^[ \t]\+//g; s/[ \t]\+$//g'

IMO sed ist das optimale Werkzeug für diesen Job. Hier kommt jedoch eine Lösung mit awk, da Sie dies verlangt haben:

awk -F', ' '{printf "%s,%s\n", $1, $2}' input.txt

Eine weitere einfache Lösung, mit der alle Leerzeichen entfernt werden können, ist tr -d:

cat input.txt | tr -d ' '
17
hek2mgl

Ich bin gerade auf dieses gestoßen. Die richtige Antwort ist:

awk 'BEGIN{FS=OFS=","} {gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)} 1'
11
Ed Morton

verwenden Sie einfach einen Regex als Trennzeichen:

', *' - für führende Räume 

'*,' - für nachgestellte Leerzeichen

sowohl für das Führen als auch für das Nachlaufen:

awk -F' *, *' '{print $1","$2}' input.txt
2
Ilya Kharlamov

Folgendes scheint zu funktionieren:

awk -F',[[:blank:]]*' '{$2=$2}1' OFS="," input.txt
2
Håkon Hægland

Wenn in Spalte zwei nur ein Satz von Leerzeichen angenommen werden kann (dies ist das ursprüngliche Beispiel): 

awk '{print $1$2}' /tmp/input.txt

Hinzufügen eines anderen Feldes, z. awk '{print $1$2$3}' /tmp/input.txt fängt zwei Gruppen von Leerzeichen auf (bis zu drei Wörter in Spalte zwei) und bricht nicht, wenn es weniger gibt. 

Wenn Sie eine unbestimmte (große) Anzahl von durch Leerzeichen getrennten Wörtern haben, würde ich einen der vorherigen Vorschläge verwenden. Andernfalls ist diese Lösung die einfachste Lösung, die Sie mit awk finden.

0
Andrew

Die einfachste Lösung ist wahrscheinlich tr zu verwenden.

$ cat -A input
^I    Name, ^IOrder  $
  Trim, working  $
cat,cat1^I  

$ tr -d '[:blank:]' < input | cat -A
Name,Order$
Trim,working$
cat,cat1
0
Fredrik Pihl