web-dev-qa-db-fra.com

Couper les espaces de début et de fin d'une chaîne dans awk

J'essaie de supprimer les espaces de début et de fin dans la deuxième colonne du input.txt ci-dessous:

Name, Order  
Trim, working
cat,cat1

J'ai utilisé la variable awk ci-dessous pour supprimer les espaces de début et de fin de la 2e colonne, mais cela ne fonctionne pas. Qu'est-ce que je rate?

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

Cela donne la sortie comme:

Name, Order  
Trim, working
cat,cat1

Les espaces de début et de fin ne sont pas supprimés.

36
Marjer

Si vous souhaitez supprimer tous les espaces, uniquement dans les lignes comportant une virgule et utiliser awk, les opérations suivantes fonctionneront pour vous:

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

Si vous souhaitez uniquement supprimer des espaces dans la deuxième colonne, remplacez l’expression par

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

Notez que gsub substitue le caractère dans // avec la deuxième expression, dans la variable qui constitue le troisième paramètre - et le fait in-place - en d'autres termes, lorsque c'est fait, le $0 (ou $2) a été modifié.

Explication complète:

-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

EDITJe tiens à souligner que la solution de @ BMW est préférable, car elle ne supprime que les espaces de début et de fin avec deux commandes gsub successives. Tout en donnant crédit, je vais vous expliquer comment cela fonctionne.

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

supprimer les espaces de début et de fin espace blanc dans la 2ème colonne

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

d'une autre manière par un gsub:

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

J'utiliserais sed:

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

Cela supprimera l’espace en tête après le ,. Sortie:

Name,Order
Trim,working
cat,cat1

Plus général peut être le suivant, il supprimera éventuellement plusieurs espaces et/ou onglets après le ,:

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

Cela fonctionnera également avec plus de deux colonnes en raison du modificateur global /g.


@Floris a demandé en discussion une solution qui supprime les espaces blancs de fin et de fin dans chaque colonne (même la première et la dernière) sans supprimer les espaces blancs au milieu d'une colonne:

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

IMO sed est l'outil optimal pour ce travail. Cependant, voici une solution avec awk car vous l'avez demandé:

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

Une autre solution simple et utile pour supprimer tous les espaces est tr -d:

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

Je viens de rencontrer ça. La bonne réponse est:

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

utilisez simplement une expression régulière comme séparateur:

', *' - pour les espaces principaux 

'*,' - pour les espaces de fin

pour le début et la fin:

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

Ce qui suit semble fonctionner:

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

S'il est prudent de ne supposer qu'un seul jeu d'espaces dans la deuxième colonne (qui est l'exemple original): 

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

Ajouter un autre champ, par exemple awk '{print $1$2$3}' /tmp/input.txt interceptera deux ensembles d'espaces (jusqu'à trois mots dans la deuxième colonne) et ne se cassera pas s'il y en a moins. 

Si vous avez un nombre indéterminé (grand) de mots délimités par des espaces, j'utiliserais l'une des suggestions précédentes, sinon cette solution est la plus simple à utiliser avec awk.

0
Andrew

La solution la plus simple est probablement d'utiliser tr

$ 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