Snij voorloop- en volgspaties uit een string in awk

Ik probeer voorloop- en volgspatie te verwijderen in de 2e kolom van de onderstaande input.txt:

Name, Order  
Trim, working
cat,cat1

Ik heb de onderstaande awkgebruikt om voorloop- en volgspaties in de 2e kolom te verwijderen, maar het werkt niet. Wat mis ik?

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

Dit geeft de output als:

Name, Order  
Trim, working
cat,cat1

Voorloop- en volgspaties worden niet verwijderd.


Antwoord 1, autoriteit 100%

Als je alle spaties wilt inkorten, alleen in regels met een komma, en awkwilt gebruiken, dan zal het volgende voor je werken:

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

Als u alleen spaties in de tweede kolom wilt verwijderen, wijzigt u de uitdrukking in

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

Merk op dat gsubhet teken in //vervangt door de tweede uitdrukking, in de variabele die de derde parameter is – en dit doet in-place– met andere woorden, als het klaar is, is de $0(of $2) gewijzigd.

Volledige uitleg:

-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

EDITIk wil erop wijzen dat de oplossing van @BMW beter is, omdat het eigenlijk alleen voorloop- en volgspaties bij twee opeenvolgende gsub-commando’s afsnijdt. Terwijl ik de eer geef, zal ik een uitleg geven over hoe het werkt.

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

Antwoord 2, autoriteit 40%

verwijder voorloop- en naloop witruimtein 2e kolom

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

op een andere manier met één gsub:

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

Antwoord 3, autoriteit 21%

Waarschuwing door @Geoff: zie mijn opmerking hieronder, slechts een van de suggesties in dit antwoord werkt (hoewel in beide kolommen).

Ik zou sedgebruiken:

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

Hiermee wordt de voorloopspatie na de , verwijderd.
Uitgang:

Name,Order
Trim,working
cat,cat1

Algemeen zou het volgende kunnen zijn, het verwijdert mogelijk meerdere spaties en/of tabs na de ,:

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

Het werkt ook met meer dan twee kolommen vanwege de globale modifier /g


@Floris vroeg in discussie om een ​​oplossing die de witruimten achteraan en aan het einde in elke kolom verwijdert (zelfs de eerste en de laatste) en geen spaties in het midden van een kolom verwijdert:

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

*BEWERKEN door @Geoff, ik heb de naam van het invoerbestand hieraan toegevoegd, en nu worden alleen alle leidende & volgspaties (hoewel uit beide kolommen). De andere suggesties in dit antwoord werken niet. Maar probeer: ” Meerdere spaties en 2 spaties ervoor hier ” *


IMO sedis de optimale tool voor deze taak. Hier komt echter een oplossing met awkomdat je daar om hebt gevraagd:

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

Een andere eenvoudige oplossing die in gedachten komt om alle spaties te verwijderen is tr -d:

cat input.txt | tr -d ' '

Antwoord 4, autoriteit 20%

Ik kwam dit net tegen. Het juiste antwoord is:

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

Antwoord 5, autoriteit 3%

gebruik gewoon een regex als scheidingsteken:

‘, *’ – voor voorloopspaties

‘ *,’ – voor volgspaties

voor zowel voor als achter:

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

Antwoord 6, autoriteit 2%

De eenvoudigste oplossing is waarschijnlijk om tr

. te gebruiken

$ cat -A input
^I    Name, ^IOrder  $
  Trim, working  $
cat,cat1^I  
$ tr -d '[:blank:]' < input | cat -A
Name,Order$
Trim,working$
cat,cat1

Antwoord 7, autoriteit 2%

Het volgende lijkt te werken:

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

Antwoord 8

Als het veilig is om slechts één set spaties in kolom twee aan te nemen (wat het originele voorbeeld is):

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

Een ander veld toevoegen, bijv. awk '{print $1$2$3}' /tmp/input.txtzal twee sets spaties opvangen (maximaal drie woorden in kolom twee), en zal niet breken als er minder zijn.

Als je een onbepaald (groot) aantal door spaties gescheiden woorden hebt, zou ik een van de vorige suggesties gebruiken, anders is deze oplossing de gemakkelijkste die je kunt vinden met awk.

Other episodes