Je voudrais supprimer tous les espaces et les tabulations de début et de fin de chaque ligne dans une sortie.
Existe-t-il un outil simple dans lequel trim
je pourrais canaliser ma sortie?
Exemple de fichier:
test space at back
test space at front
TAB at end
TAB at front
sequence of some space in the middle
some empty lines with differing TABS and spaces:
test space at both ends
Réponses:
ou plus court:
Souhaitez-vous couper l'espace de début et de fin ou les caractères de tabulation 1 et aussi presser des séquences de tabulations et d'espaces dans un seul espace.
Cela fonctionne parce que lorsque vous affectez quelque chose à l’un des champs ,
awk
reconstruit l’enregistrement complet (tel qu’imprimé parprint
) en joignant tous les champs ($1
, ...,$NF
) avecOFS
(espace par défaut).1 (et éventuellement d'autres caractères vides en fonction des paramètres régionaux et de la
awk
mise en œuvre)la source
awk '{$1=$1}1'
;
c'est requis dans la syntaxe standard de awkecho -e 'foo \t bar' | awk '{$1=$1};1'
echo ' hello ' | xargs
La commande peut être condensée comme si vous utilisiez GNU
sed
:Exemple
Voici la commande ci-dessus en action.
Vous pouvez utiliser
hexdump
pour confirmer que lased
commande supprime correctement les caractères souhaités.Cours de caractère
Vous pouvez également utiliser des noms de classe de caractères au lieu de lister littéralement les ensembles de la manière suivante
[ \t]
:Exemple
La plupart des outils GNU utilisant des expressions régulières (regex) prennent en charge ces classes.
Utiliser ces jeux au lieu de jeux littéraux semble toujours un gaspillage d’espace, mais si vous souhaitez que votre code soit portable ou que vous ayez à traiter avec des jeux de caractères différents (think international), vous voudrez probablement utiliser les noms de classe. au lieu.
Références
la source
[[:space:]]
n’est pas équivalent à[ \t]
dans le cas général (unicode, etc.).[[:space:]]
sera probablement beaucoup plus lent (car il y a beaucoup plus de types d'espaces dans unicode que juste' '
et'\t'
). Même chose pour tous les autres.sed 's/^[ \t]*//'
n'est pas portable. Finalement, POSIX exige même de supprimer une séquence d’espace, une barre oblique inverse ou dest
caractères, et c’est ce que GNU faitsed
égalementPOSIXLY_CORRECT
dans l’environnement.sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
Comme suggéré par Stéphane Chazelas dans la réponse acceptée, vous pouvez maintenant
créer un script
/usr/local/bin/trim
:et donnez à ce fichier les droits exécutables:
Maintenant, vous pouvez passer chaque sortie à
trim
par exemple:(pour les commentaires ci-dessous: je l'ai déjà utilisé:
while read i; do echo "$i"; done
ce qui fonctionne aussi très bien, mais est moins performant)
la source
while read -r line
pour préserver antislashs et encore ... . En ce qui concerne les fichiers volumineux / la vitesse, vous avez vraiment choisi la pire solution. Je ne pense pas qu'il y ait pire. Voir les réponses dans Pourquoi utiliser une boucle shell pour traiter du texte une mauvaise pratique? y compris mon commentaire sur la dernière réponse où j'ai ajouté un lien à un repère de vitesse. Lessed
réponses ici sont parfaitement bien IMO et bien mieux queread
.-
et suivies d'une combinaison de 1 ou plusieurs caractères e, E ou n, et / ou contenant des caractères NUL. En outre, une ligne non terminée après la dernière nouvelle ligne sera ignorée.xargs sans arguments le fait.
Exemple:
la source
xargs
cela échouera si l'entrée contient des barres obliques inverses et des guillemets simples.echo
invocations. Certaines implémentations d'écho traiteront également les options et / ou les barres obliques inverses ... Cela ne fonctionne également que pour une entrée sur une seule ligne.Si vous lisez une ligne dans une variable shell, le faites-vous
read
déjà sauf instruction contraire .la source
read
. Donc, si vous continuez à lire, cela fonctionne:cat file | while read i; do echo $i; done
echo "$i"
pour voir le véritable effet de laread
Si vous stockez des lignes en tant que variables, vous pouvez utiliser bash pour effectuer le travail:
supprime les espaces de début d'une chaîne:
supprime les espaces de fin d'une chaîne:
supprime tous les espaces d'une chaîne:
la source
Pour supprimer tous les espaces de début et de fin d'une ligne donnée à l'aide d'un outil «canalisé», je peux identifier 3 manières différentes qui ne sont pas complètement équivalentes. Ces différences concernent les espaces entre les mots de la ligne de saisie. En fonction du comportement attendu, vous ferez votre choix.
Exemples
Pour expliquer les différences, considérons cette ligne de saisie factice:
tr
tr
est vraiment une commande simple. Dans ce cas, il supprime tout espace ou caractère de tabulation.awk
awk
supprime les espaces de début et de fin et réduit en un espace unique chaque espace entre les mots.sed
Dans ce cas,
sed
supprime les espaces de début et de fin sans toucher les espaces entre les mots.Remarque:
Dans le cas d'un mot par ligne,
tr
fait le travail.la source
[:space:]
, au lieu de [: blank:], pour la commandetr
, comme::... | tr -d [:space:]
, supprimer également les nouvelles lignes. (voir:man tr
)sed est un excellent outil pour cela:
Vous pouvez l’utiliser pour votre cas soit en lisant le texte, par exemple
ou en agissant dessus 'inline' si vous
sed
êtes GNU:Mais changer le code source de cette manière est "dangereux", car il peut être irrécupérable s’il ne fonctionne pas correctement (ou même quand cela fonctionne!), faites donc une sauvegarde en premier (ou utilisez-en un
-i.bak
qui présente également l’avantage d’être portable sur certains BSDsed
). !la source
traduire la commande fonctionnerait
la source
Si la chaîne que vous essayez d'ajuster est courte et continue / contiguë, vous pouvez simplement la transmettre en tant que paramètre à n'importe quelle fonction bash:
la source