web-dev-qa-db-fra.com

Comment découper les espaces de début et de fin de chaque ligne d'une 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 dans lequel je pourrais diriger 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 
189
rubo77
awk '{$1=$1;print}'

ou plus court:

awk '{$1=$1};1'

Ajusterait les espaces ou les tabulations de début et de fin1 et aussi comprime des séquences de tabulations et d'espaces dans un seul espace.

Cela fonctionne parce que lorsque vous assignez quelque chose à l'un des champs, awk reconstruit l'enregistrement entier (tel qu'imprimé par print) en joignant tous les champs ($1, ..., $NF) avec OFS (espace par défaut).

1(et éventuellement d'autres caractères vides en fonction des paramètres régionaux et de l'implémentation awk)

242

La commande peut être condensée comme 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 personnages

Vous pouvez également utiliser des noms de classe de caractères au lieu de lister littéralement les ensembles comme celui-ci, [ \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 des expressions régulières (regex) prennent en charge ces classes.

 [[:alnum:]]  - [A-Za-z0-9]     Alphanumeric characters
 [[:alpha:]]  - [A-Za-z]        Alphabetic characters
 [[:blank:]]  - [ \x09]         Space or tab characters only
 [[:cntrl:]]  - [\x00-\x19\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]       All whitespace chars
 [[:upper:]]  - [A-Z]           Upper-case alphabetic characters
 [[:xdigit:]] - [0-9a-fA-F]     Hexadecimal digit characters

Les utiliser à la place des ensembles littéraux semble toujours être une perte d'espace, mais si vous vous souciez de la portabilité de votre code ou de la gestion d'autres jeux de caractères (pensez à l'international), vous voudrez probablement utiliser les noms de classe au lieu.

Références

57
slm

xargs sans arguments le fait.

Exemple:

trimmed_string=$(echo "no_trimmed_string" | xargs) 
27
Newton_Jose

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

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

et donnez à ce fichier les droits exécutables:

chmod +x /usr/local/bin/trim

Vous pouvez maintenant passer chaque sortie à trim par exemple:

cat file | trim

(pour les commentaires ci-dessous: je l'ai utilisé avant: while read i; do echo "$i"; done
qui fonctionne aussi bien, mais est moins performant)

25
rubo77
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'

Si vous lisez une ligne dans une variable Shell, read le fait déjà sauf indication contraire .

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

supprimer le premier espace d'une chaîne:

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

supprimer les espaces de fin d'une chaîne:

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

supprimer tous les espaces d'une chaîne:

echo ${text//[[:space:]]}
17
Łukasz Rajchel

Pour supprimer tous les espaces de début et de fin d'une ligne donnée grâce à un outil 'canalisé', je peux identifier 3 façons différentes qui ne sont pas complètement équivalentes. Ces différences concernent les espaces entre les mots de la ligne d'entrée. En fonction du comportement attendu, vous ferez votre choix.

Exemples

Pour expliquer les différences, considérons cette ligne d'entrée fictive:

"   \t  A   \tB\tC   \t  "

tr

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

tr est vraiment 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 aucun espace entre les mots.

Remarque:

Dans le cas d'un mot par ligne, tr fait le travail.

15
frozar

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 l'utiliser pour votre cas soit dans le texte, par exemple.

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

ou en agissant dessus "en ligne" si votre sed est le GNU one:

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 c'est le cas!), donc sauvegardez d'abord (ou utilisez -i.bak qui a également l'avantage d'être portable sur certains BSD seds)!

6
Michael Durrant

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]) par des caractères arbitraires pour couper ou utiliser .lstrip() ou .rstrip() selon les besoins.

Comme réponse de rubo77 , enregistrez en tant que script /usr/local/bin/trim Et accordez les autorisations avec chmod +x.

4
qwr

traduire la commande fonctionnerait

cat file | tr -d [:blank:]
2
Srinagesh

J'ai é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 l'analyse de l'enregistrement de l'ensemble
séparateur à aucun, c'est-à-dire traiter toute l'entrée comme
un seul enregistrement

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

/^[\n\t ]*|[\n\t ]*$/:
de cette chaîne attrape tout espace de nouvelle ligne et tabulation pré
ou publier un espace de nouvelle ligne et une classe d'onglets et les remplacer par
chaîne vide

print;exit: Puis imprimez et quittez

"$1":
et passez le premier argument de la fonction à
processus par awk

comment utiliser:
copiez le code ci-dessus, collez-le dans Shell, puis entrez dans
définit la fonction.
alors vous pouvez utiliser awkcliptor comme commande avec le premier argument comme fichier d'entrée

exemple d'utilisation:

echo '
 ggggg    

      ' > a_file
awkcliptor a_file

production:

ggggg

ou

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

production:

ggggg
1

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

    trim(){
        echo $@
    }

    a="     some random string   "

    echo ">>`trim $a`<<"
Output
>>some random string<<
1
Subrata Das
trimpy () {
    python3 -c 'import sys
for line in sys.stdin: print(line.strip())'
}
trimsed () {
gsed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
# example usage
echo " hi " | trimpy

Bonus: remplacez str.strip([chars]) par des caractères arbitraires pour rogner ou utilisez .lstrip() ou .rstrip() selon vos besoins.

(Ceci n'est qu'un remix d'autres réponses ici.)

0
HappyFace