Comment supprimer les espaces blancs de début et de fin de chaque ligne dune sortie?

Je voudrais supprimer tous les espaces et tabulations de début et de fin de chaque ligne dans une sortie.

Existe-t-il un outil simple comme trim Je pourrais diriger ma sortie vers?

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 

Commentaires

  • À quiconque cherche ici une solution pour supprimer les sauts de ligne, cest un problème différent. Par définition, une nouvelle ligne crée une nouvelle ligne de texte. Par conséquent, une ligne de texte ne peut pas contenir de nouvelle ligne. La question que vous souhaitez poser est de savoir comment supprimer une nouvelle ligne au début ou à la fin dune chaîne: stackoverflow.com/questions/369758 , ou comment supprimer un espace vide lignes ou lignes qui ne sont que des espaces: serverfault.com/questions/252921

Réponse

awk "{$1=$1;print}" 

ou plus court:

awk "{$1=$1};1" 

Réduirait le début et espace de fin ou caractères de tabulation 1 et aussi séquences de tabulations et des espaces dans un seul espace.

Cela fonctionne car lorsque vous attribuez quelque chose à lun des champs , awk reconstruit tout lenregistrement (tel quimprimé par print) en joignant tous les champs ($1, …, $NF) avec OFS (espace par défaut).

1 (et éventuellement un autre caractère vide s en fonction de la langue et de la awk implémentation)

Commentaires

  • Point-virgule allumé le deuxième exemple est superflu. Peut utiliser: awk '{$1=$1}1'
  • @Brian, non, le ; est requis dans la syntaxe awk standard
  • Intéressant … Aucun point-virgule nest pris en charge par gawk, mawk et OS X ‘ s awk. (Au moins pour mes versions (1.2, 4.1.1 et 20070501, respectivement)
  • La seule chose que je naime pas ‘ dans cette approche, cest que vous perdre les espaces répétitifs dans la ligne. Par exemple, echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

Réponse

La commande peut être condensée comme ceci si vous « utilisez GNU sed:

$ sed "s/^[ \t]*//;s/[ \t]*$//" < file 

Exemple

Voici la commande ci-dessus en action.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah 

Vous pouvez utiliser hexdump pour confirmer que la commande sed supprime correctement les caractères souhaités.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009 

Classes de caractères

Vous pouvez également utiliser des noms de classes de caractères au lieu de lister littéralement les ensembles comme ceci, [ \t]:

$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file 

Exemple

$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" 

La plupart des outils GNU qui utilisent l’expression régulière ssions (regex) supportent ces classes (ici avec leur équivalent dans la locale C typique dun système ASCII (et là uniquement)).

 [[:alnum:]] - [A-Za-z0-9] Alphanumeric characters [[:alpha:]] - [A-Za-z] Alphabetic characters [[:blank:]] - [ \t] Space or tab characters only [[:cntrl:]] - [\x00-\x1F\x7F] Control characters [[:digit:]] - [0-9] Numeric characters [[:graph:]] - [!-~] Printable and visible characters [[:lower:]] - [a-z] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f\n\r] All whitespace chars [[:upper:]] - [A-Z] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters 

Utilisation ceux-ci au lieu de jeux littéraux semblent toujours être une perte despace, mais si vous êtes préoccupé par le fait que votre code soit portable ou que vous ayez à gérer des jeux de caractères alternatifs (pensez à linternational), vous voudrez probablement utiliser les noms de classe à la place .

Références

Commentaires

  • Notez que [[:space:]] nest 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 despaces blancs en Unicode que simplement ' ' et '\t'). Même chose pour tous les autres.
  • sed 's/^[ \t]*//' nest pas portable. Finalement, POSIX exige même que pour supprimer une séquence de caractères despace, de barre oblique inverse ou de t, et que ‘ est ce que GNU sed le fait également lorsque POSIXLY_CORRECT est dans lenvironnement.
  • Que faire si je veux couper les caractères de nouvelle ligne? ‘ \ n \ n text \ n \ n ‘
  • Jaime la solution sed en raison de labsence de dautres effets secondaires comme dans la solution awk. La première variante ne fonctionne pas lorsque je lai essayé en bash sur OSX jsut maintenant, mais la version de la classe de caractères fonctionne: sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukov voir mon commentaire sur le message dorigine

Réponse

xargs sans arguments font cela.

Exemple:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

Commentaires

  • Cela réduit également plusieurs espaces dans une ligne, qui na pas été demandée dans la question
  • @roaima – true mais la réponse acceptée serre également les espaces (ce qui na pas été demandé dans la question). Je pense que le vrai problème ici est que xargs échouera si lentrée contient des barres obliques inverses et des guillemets simples.
  • @don_crissti qui ne ‘ t signifie que la réponse acceptée répond correctement à la question posée, cependant. Mais dans ce cas ici, il nétait pas ‘ t marqué comme une mise en garde alors que dans la réponse acceptée cétait le cas. Jespère que jai ‘ souligné le fait au cas où cela ‘ serait pertinent pour un futur lecteur.
  • Cela aussi coupures sur les guillemets simples, les guillemets doubles, les caractères anti-slash Il exécute également une ou plusieurs invocations echo. Certaines implémentations décho traiteront également des options et / ou des barres obliques inverses … Cela ne fonctionne également que pour une entrée sur une seule ligne.

Answer

Comme suggéré par Stéphane Chazelas dans la réponse acceptée, vous pouvez maintenant
créer un script /usr/local/bin/trim:

#!/bin/bash awk "{$1=$1};1" 

et donnez à ce fichier des droits exécutables:

chmod +x /usr/local/bin/trim 

Vous pouvez maintenant transmettre chaque sortie à trim par exemple:

cat file | trim 

(pour les commentaires ci-dessous: jai déjà utilisé ceci: while read i; do echo "$i"; done
qui fonctionne également très bien, mais est moins performant)

Commentaires

  • Bonne chance si votre fichier est volumineux et / ou contient des contre-obliques.
  • @don_crissti: pourriez-vous commenter un peu plus?, Quelle solution convient mieux aux fichiers volumineux, et comment pourrais-je modifier ma solution si le fichier contenait des barres obliques inverses?
  • Vous ‘ devrez utiliser while read -r line pour conserver les contre-obliques et même dans ce cas … . En ce qui concerne les fichiers / vitesse énormes, vous avez vraiment choisi la pire solution. Je ne ‘ ne pense pas que ‘ s quelque chose de pire là-bas. Voir les réponses sur Pourquoi utiliser une boucle shell pour traiter du texte est une mauvaise pratique? y compris mon commentaire sur la dernière réponse où jai ajouté un lien vers un benchmark de vitesse. Les réponses sed ici sont parfaitement correctes IMO et bien meilleures que read.
  • Vous pouvez également ajouter un alias dans / etc / profile (ou votre alias ~ / .bashrc ou ~ / .zshrc etc …) trim =  » awk ‘ { \ $ 1 = \ $ 1}; 1 ‘  »
  • Pas besoin de bash, vous pouvez le créer #! /usr/bin/awk -f {$1=$1};1. (attention cependant aux noms de fichiers contenant = caractères)

Réponse

Si vous stockez des lignes en tant que variables, vous pouvez utiliser bash pour faire le travail:

supprimer les espaces au début dune chaîne:

shopt -s extglob echo ${text##+([[:space:]])} 

supprimer les espaces de fin dune chaîne:

shopt -s extglob echo ${text%%+([[:space:]])} 

supprimer tous les espaces dune chaîne:

echo ${text//[[:space:]]} 

Commentaires

  • Supprimer tous les espaces dune chaîne nest pas la même chose que supprimer les espaces de début et de fin (comme dans la question).
  • De loin la meilleure solution – elle ne nécessite que des fonctions intégrées bash et aucune fourche de processus externe.
  • Nice. Les scripts sexécutent BEAUCOUP plus vite sils nont ‘ pas à intégrer des programmes extérieurs (tels que awk ou sed). Cela fonctionne également avec les versions  » modernes  » (93u +) de ksh.

Réponse

sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" 

Si vous « lisez une ligne dans une variable shell, read fait déjà cela sauf indication contraire .

Commentaires

  • +1 pour read. Donc, si vous pointez vers pendant la lecture, cela fonctionne: cat file | while read i; do echo $i; done
  • @rubo sauf que dans votre exemple, la variable sans guillemets est également retraitée par le shell. Utilisez echo "$i" pour voir le véritable effet de read

Réponse

Pour supprimer tous les espaces de début et de fin dune ligne donnée grâce à un outil « piped », je peux identifier 3 différents des voies qui ne sont pas tout à fait équivalentes. Ces différences concernent les espaces entre les mots de la ligne dentrée. En fonction du b attendu ehaviour, vous ferez votre choix.

Exemples

Pour expliquer les différences, considérons cette ligne dentrée factice:

" \t A \tB\tC \t " 

tr

$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC 

tr est en réalité une commande simple. Dans ce cas, il supprime tout espace ou caractère de tabulation.

awk

$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C 

awk supprime les espaces de début et de fin et réduit à un seul espace tous les espaces entre les mots.

sed

$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C 

Dans ce cas, sed supprime les espaces de début et de fin sans toucher aux espaces entre les mots.

Remarque:

Dans le cas dun mot par ligne, tr fait le travail.

Commentaires

  • Aucun de ces éléments ne supprime les nouvelles lignes de fin / de tête
  • +1 pour une liste de solutions avec leur sortie (parfois inattendue).
  • @ user61382 cest plutôt tard, mais voyez mon commentaire sur le message original.
  • @highmaintenance: utilisez [:space:], au lieu de [: blank:], pour la commande tr, comme: ... | tr -d [:space:], pour supprimer également les nouvelles lignes. (voir: man tr)

Réponse

sed est un excellent outil pour cela:

 # substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/) 

Vous pouvez lutiliser pour votre cas soit dans le texte, par exemple

<file sed -e "s/^[[... 

ou en agissant dessus « en ligne » si votre sed est celui de GNU:

sed -i "s/..." file 

mais changer la source de cette façon est « dangereux » car il peut être irrécupérable quand cela ne fonctionne pas correctement (ou même quand cela fonctionne!), alors sauvegardez dabord (ou utilisez -i.bak qui a également lavantage dêtre portable sur certains BSD sed s)!

Réponse

Une réponse que vous pouvez comprendre en un coup dœil:

#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip()) 

Bonus: remplacez str.strip([chars]) avec des caractères arbitraires pour couper ou utiliser .lstrip() ou .rstrip() selon les besoins.

Comme rubo77 « sa nswer , enregistrez en tant que script /usr/local/bin/trim et accordez les autorisations avec chmod +x.

Réponse

Si la chaîne que lon essaie de couper est courte et continue / contiguë, on peut simplement la passer en paramètre à nimporte quelle fonction bash:

 trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<< 

Answer

Jai écrit cette fonction shell en utilisant awk

awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; } 

BEGIN{ RS="^$" }:
au début avant de commencer lanalyse set record
separator to none cest-à-dire traiter toute lentrée comme
un seul enregistrement

gsub(this,that):
remplacer cette expression rationnelle par cette chaîne

/^[\n\t ]*|[\n\t ]*$/:
de cette chaîne attraper tout espace avant nouvelle ligne et toute classe de tabulation
ou publier un espace de nouvelle ligne et une classe de tabulation et les remplacer par
chaîne vide

print;exit: puis imprimez et quittez

"$1":
et passez le premier argument de la fonction à be
process by awk

comment utiliser:
copier le code ci-dessus, coller dans le shell, puis entrer pour
définir la fonction.
alors vous pouvez utiliser awkcliptor comme commande avec le premier argument comme fichier dentrée

exemple dutilisation:

echo " ggggg " > a_file awkcliptor a_file 

sortie:

ggggg 

ou

echo -e "\n ggggg \n\n "|awkcliptor 

sortie:

ggggg 

Commentaires

  • Pouvez-vous expliquer la différence uniquement avec awk '{$1=$1};1'?

Réponse

Pour ceux dentre nous qui nont pas assez despace dans le cerveau pour se souvenir de la syntaxe sed obscure, inversez simplement la chaîne , coupez le premier champ avec un délimiteur despace et inversez-le à nouveau.

cat file | rev | cut -d" " -f1 | rev 

Commentaires

  • Cela ne fonctionne que sil ny a pas plus dun espace devant chaque ligne et pas plus dun mot dans une ligne.

Réponse

trimpy () { python3 -c "import sys for line in sys.stdin: print(line.strip())" } trimsed () { gsed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" } trimzsh () { local out="$(</dev/stdin)" [[ "$out" =~ "^\s*(.*\S)\s*$" ]] && out="$match[1]" || out="" print -nr -- "$out" } # example usage echo " hi " | trimpy 

Bonus: remplacez str.strip([chars]) par des caractères arbitraires pour couper ou utiliser ou .rstrip() selon les besoins.

Réponse

La commande translate fonctionnerait

cat file | tr -d [:blank:] 

Commentaires

  • Cette commande nest pas correcte car elle supprime tous les espaces du fichier, pas seulement les espaces de début / fin.
  • @BrianRedbeard Vous avez raison. Cest toujours une réponse utile pour une chaîne monolithique, sans espaces.

Réponse

pour lexemple bash:

alias trim="awk "{\$1=\$1};1"" 

utilisation:

echo -e " hello\t\tkitty " | trim | hexdump -C 

résultat:

00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c 

Commentaires

  • La réponse awk '{$1=$1};1' a été donnée il y a longtemps. Lidée den faire un alias a été suggérée dans un commentaire il y a presque aussi longtemps. Oui, vous êtes autorisé à prendre le commentaire de quelquun dautre et à en faire une réponse. Mais si vous le faites, vous devriez donner du crédit aux personnes qui ont posté lidée avant vous. Et cest une extension si triviale de la réponse acceptée que cela ne vaut pas vraiment la peine.
  • Lidée était de créer un alias. Je nai ‘ pas vu cette réponse auparavant.
  • et deuxième chose de la pile:  » Merci pour vos commentaires! Les votes exprimés par ceux qui ont moins de 15 points de réputation sont enregistrés, mais ne modifient pas le score affiché publiquement.  »

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *