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
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
)
La commande peut être condensée comme si vous utilisez GNU sed
:
$ sed 's/^[ \t]*//;s/[ \t]*$//' < file
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
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
$ 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.
xargs sans arguments le fait.
Exemple:
trimmed_string=$(echo "no_trimmed_string" | xargs)
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)
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:
shopt -s extglob
echo ${text##+([[:space:]])}
shopt -s extglob
echo ${text%%+([[:space:]])}
echo ${text//[[:space:]]}
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.
Pour expliquer les différences, considérons cette ligne d'entrée fictive:
" \t A \tB\tC \t "
$ 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.
$ 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.
$ 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.
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 sed
s)!
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
.
traduire la commande fonctionnerait
cat file | tr -d [:blank:]
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
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<<
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.)