J'ai un script shell avec ce code:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
Mais le code conditionnel est toujours exécuté car hg st
imprime toujours au moins un caractère de nouvelle ligne.
$var
(comme trim()
dans PHP )?ou
Je pourrais utiliser sed ou AWK , mais j'aimerais penser qu'il existe une solution plus élégante à ce problème.
Définissons une variable contenant les espaces de début, de fin et intermédiaires:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
Comment supprimer tous les espaces (notés [:space:]
dans tr
):
FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12
Comment supprimer les espaces blancs uniquement:
FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15
Comment supprimer les espaces finaux uniquement:
FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15
Comment supprimer les espaces de début et de fin - chaînez le sed
s:
FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14
Alternativement, si votre bash le supporte, vous pouvez remplacer echo -e "${FOO}" | sed ...
par sed ... <<<${FOO}
, comme suit (pour les espaces finaux):
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
Une réponse simple est:
echo " lol " | xargs
Xargs fera le rognage pour vous. C'est une commande/programme, sans paramètre, retourne la chaîne coupée, aussi simple que cela!
Remarque: ceci ne supprime pas les espaces internes, donc "foo bar"
reste inchangé. Cela ne devient PAS "foobar"
.
Il existe une solution qui utilise uniquement les fonctions intégrées de Bash appelées caractères génériques :
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
echo "===$var==="
Voici la même chose enveloppée dans une fonction:
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
echo -n "$var"
}
Vous passez la chaîne à couper en forme entre guillemets. par exemple.:
trim " abc "
Une bonne chose à propos de cette solution est qu’elle fonctionnera avec n’importe quel shell compatible POSIX.
Bash a une fonctionnalité appelée expansion des paramètres, qui permet, entre autres, le remplacement de chaînes basé sur ce qu'on appelle patterns (les patterns ressemblent à des expressions régulières, mais il existe des différences et des limitations fondamentales ). [La ligne d'origine de flussence: Bash a des expressions régulières, mais elles sont bien cachées:]
Ce qui suit montre comment supprimer tout un espace (même de l'intérieur) d'une valeur de variable.
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
Afin de supprimer tous les espaces du début et de la fin d'une chaîne (y compris les caractères de fin de ligne):
echo $variable | xargs echo -n
Cela supprimera également les espaces en double:
echo " this string has a lot of spaces " | xargs echo -n
Produit: 'cette chaîne a beaucoup d'espaces'
trim()
{
local trimmed="$1"
# Strip leading space.
trimmed="${trimmed## }"
# Strip trailing space.
trimmed="${trimmed%% }"
echo "$trimmed"
}
Par exemple:
test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"
Sortie:
'one leading', 'one trailing', 'one leading and one trailing'
trim()
{
local trimmed="$1"
# Strip leading spaces.
while [[ $trimmed == ' '* ]]; do
trimmed="${trimmed## }"
done
# Strip trailing spaces.
while [[ $trimmed == *' ' ]]; do
trimmed="${trimmed%% }"
done
echo "$trimmed"
}
Par exemple:
test4="$(trim " two leading")"
test5="$(trim "two trailing ")"
test6="$(trim " two leading and two trailing ")"
echo "'$test4', '$test5', '$test6'"
Sortie:
'two leading', 'two trailing', 'two leading and two trailing'
Vous pouvez couper simplement avec echo
:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
De la section du guide Bash sur globbing
Pour utiliser un extglob dans une extension de paramètre
#Turn on extended globbing
shopt -s extglob
#Trim leading and trailing whitespace from a variable
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}
#Turn off extended globbing
shopt -u extglob
Voici la même fonctionnalité encapsulée dans une fonction (REMARQUE: nécessité de citer la chaîne d'entrée transmise à la fonction):
trim() {
# Determine if 'extglob' is currently on.
local extglobWasOff=1
shopt extglob >/dev/null && extglobWasOff=0
(( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
# Trim leading and trailing whitespace
local var=$1
var=${var##+([[:space:]])}
var=${var%%+([[:space:]])}
(( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
echo -n "$var" # Output trimmed string.
}
Usage:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
Si nous modifions la fonction pour qu'elle s'exécute dans un sous-shell, nous n'avons pas à nous soucier d'examiner l'option Shell actuelle pour extglob, nous pouvons simplement la définir sans affecter le Shell actuel. Cela simplifie énormément la fonction. Je mets également à jour les paramètres de position "en place", donc je n'ai même pas besoin d'une variable locale
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
alors:
$ s=$'\t\n \r\tfoo '
$ shopt -u extglob
$ shopt extglob
extglob off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo '<
>foo<
$ shopt extglob
extglob off
Avec les fonctionnalités étendues de correspondance de modèle de Bash activées (shopt -s extglob
), vous pouvez utiliser ceci:
{trimmed##*( )}
pour supprimer une quantité arbitraire d'espaces de début.
Je l'ai toujours fait avec sed
var=`hg st -R "$path" | sed -e 's/ *$//'`
S'il existe une solution plus élégante, j'espère que quelqu'un la publiera.
Vous pouvez supprimer des nouvelles lignes avec tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
# Trim whitespace from both ends of specified parameter
trim () {
read -rd '' $1 <<<"${!1}"
}
# Unit test for trim()
test_trim () {
local foo="$1"
trim foo
test "$foo" = "$2"
}
test_trim hey hey &&
test_trim ' hey' hey &&
test_trim 'ho ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim ' hey ho ' 'hey ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
Il y a beaucoup de réponses, mais je crois toujours que le script que je viens d'écrire mérite d'être mentionné pour les raisons suivantes:
"$*"
joint plusieurs arguments en utilisant un espace. si vous voulez couper et afficher uniquement le premier argument, utilisez plutôt "$1"
Le scénario:
trim() {
local s2 s="$*"
# note: the brackets in each of the following two lines contain one space
# and one tab
until s2="${s#[ ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
until s2="${s%[ ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
echo "$s"
}
Usage:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
Sortie:
>here is
something<
Vous pouvez utiliser old-school tr
. Par exemple, cela renvoie le nombre de fichiers modifiés dans un référentiel git, espaces blancs supprimés.
MYVAR=`git ls-files -m|wc -l|tr -d ' '`
Cela a fonctionné pour moi:
text=" trim my edges "
trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back
echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed
#Result
<trim my edges>
Pour mettre cela sur moins de lignes pour le même résultat:
text=" trim my edges "
trimmed=${${text##+( )}%%+( )}
# Strip leading and trailing white space (new line inclusive).
trim(){
[[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
printf "%s" "$BASH_REMATCH"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
[[ "$1" =~ [^[:space:]].* ]]
printf "%s" "$BASH_REMATCH"
}
# Strip trailing white space (new line inclusive).
rtrim(){
[[ "$1" =~ .*[^[:space:]] ]]
printf "%s" "$BASH_REMATCH"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
OR
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
OR
# Strip leading specified characters. ex: str=$(ltrim "$str" $'\n a')
ltrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip trailing specified characters. ex: str=$(rtrim "$str" $'\n a')
rtrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}
OR
S'appuyant sur l'expruution de moskit ...
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}
# Strip trailing white space (new line inclusive).
rtrim(){
printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
J'ai vu des scripts simplement utiliser une affectation de variable pour faire le travail:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Les espaces sont automatiquement fusionnés et ajustés. Il faut faire attention aux métacaractères de Shell (risque d'injection potentiel).
Je recommanderais également de toujours citer deux fois les substitutions de variables dans les conditions de Shell:
if [ -n "$var" ]; then
car quelque chose comme un -o ou un autre contenu dans la variable pourrait modifier vos arguments de test.
var=' a b c '
trimmed=$(echo $var)
Je voudrais simplement utiliser sed:
function trim
{
echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}
a) Exemple d'utilisation sur une chaîne d'une seule ligne
string=' wordA wordB wordC wordD '
trimmed=$( trim "$string" )
echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"
Sortie:
GIVEN STRING: | wordA wordB wordC wordD |
TRIMMED STRING: |wordA wordB wordC wordD|
b) Exemple d'utilisation sur une chaîne multiligne
string=' wordA
>wordB<
wordC '
trimmed=$( trim "$string" )
echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"
Sortie:
GIVEN STRING: | wordAA
>wordB<
wordC |
TRIMMED STRING: |wordAA
>wordB<
wordC|
c) Note finale:
Si vous n'aimez pas utiliser une fonction, pour chaîne sur une seule ligne, vous pouvez simplement utiliser une commande "plus facile à mémoriser" comme:
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Exemple:
echo " wordA wordB wordC " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Sortie:
wordA wordB wordC
Utilisation de ce qui précède sur les chaînes multilignes fonctionneront également, mais veuillez noter que cela supprimera également tout espace interne multiple de fin/précédant également, comme GuruM l’a remarqué dans les commentaires.
string=' wordAA
>four spaces before<
>one space before< '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Sortie:
wordAA
>four spaces before<
>one space before<
Donc si vous voulez garder ces espaces, utilisez la fonction au début de ma réponse!
d) EXPLICATION de la syntaxe sed "trouver et remplacer" sur les chaînes multilignes utilisées dans la fonction trim:
sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
# Copy from the hold to the pattern buffer
g
# Do the search and replace
s/^[ \t]*//g
s/[ \t]*$//g
# print
p
}'
Utilisez AWK:
echo $var | awk '{gsub(/^ +| +$/,"")}1'
Pour supprimer des espaces et des tabulations de gauche à première Word, entrez:
echo " This is a test" | sed "s/^[ \t]*//"
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-Word.html
Voici une fonction trim () qui réduit et normalise les espaces
#!/bin/bash
function trim {
echo $*
}
echo "'$(trim " one two three ")'"
# 'one two three'
Et une autre variante qui utilise des expressions régulières.
#!/bin/bash
function trim {
local trimmed="$@"
if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
then
trimmed=${BASH_REMATCH[1]}
fi
echo "$trimmed"
}
echo "'$(trim " one two three ")'"
# 'one two three'
Cela ne pose pas le problème de la suppression non souhaitée, mais l'espace blanc intérieur n'est pas modifié (en supposant que $IFS
est défini sur la valeur par défaut, qui est ' \t\n'
).
Il lit jusqu'à la première nouvelle ligne (sans l'inclure) ou à la fin de la chaîne, selon la première éventualité, et supprime tout mélange d'espaces de début et de fin et de caractères \t
. Si vous souhaitez conserver plusieurs lignes (et également supprimer les nouvelles lignes), utilisez read -r -d '' var << eof
à la place; notez cependant que si votre entrée contient \neof
, elle sera coupée juste avant. (D'autres formes d'espace blanc, à savoir \r
, \f
et \v
, sont pas supprimées, même si vous les ajoutez à $ IFS.)
read -r var << eof
$var
eof
Les affectations ignorent les espaces de début et de fin et peuvent donc être utilisées pour découper:
$ var=`echo ' hello'`; echo $var
hello
Cela supprimera tous les espaces de votre chaîne,
VAR2="${VAR2//[[:space:]]/}"
/
remplace la première occurrence et //
toutes les occurrences de blancs dans la chaîne. C'est à dire. tous les espaces blancs sont remplacés par - rien
C'est la méthode la plus simple que j'ai vue. Il n'utilise que Bash, quelques lignes seulement, l'expression rationnelle est simple et correspond à toutes les formes d'espaces:
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
Voici un exemple de script pour le tester:
test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t \n ")
echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested" # Ugh!
echo "----------"
echo
echo "Ugh! Let's fix that..."
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
echo
echo "----------"
echo -e "Testing:${test}:Tested" # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
Python a une fonction strip()
qui fonctionne de manière identique à trim()
de PHP. Nous pouvons donc faire un peu en ligne Python pour en faire un utilitaire facilement compréhensible:
alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'
Cela supprimera les espaces de début et de fin (y compris les nouvelles lignes).
$ x=`echo -e "\n\t \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi
trim () supprime les espaces (et les tabulations, caractères non imprimables; je considère simplement les espaces pour plus de simplicité). Ma version d'une solution:
var="$(hg st -R "$path")" # I often like to enclose Shell output in double quotes
var="$(echo "${var}" | sed "s/\(^ *\| *\$\)//g")" # This is my suggestion
if [ -n "$var" ]; then
echo "[${var}]"
fi
La commande 'sed' supprime uniquement les espaces blancs de début et de fin, mais elle peut également être transmise à la première commande, ce qui entraîne:
var="$(hg st -R "$path" | sed "s/\(^ *\| *\$\)//g")"
if [ -n "$var" ]; then
echo "[${var}]"
fi
#!/bin/bash
function trim
{
typeset trimVar
eval trimVar="\${$1}"
read trimVar << EOTtrim
$trimVar
EOTtrim
eval $1=\$trimVar
}
# Note that the parameter to the function is the NAME of the variable to trim,
# not the variable contents. However, the contents are trimmed.
# Example of use:
while read aLine
do
trim aline
echo "[${aline}]"
done < info.txt
# File info.txt contents:
# ------------------------------
# ok hello there $
# another line here $
#and yet another $
# only at the front$
#$
# Output:
#[ok hello there]
#[another line here]
#[and yet another]
#[only at the front]
#[]
J'ai trouvé que je devais ajouter du code à partir d'une sortie désordonnée sdiff
afin de le nettoyer:
sdiff -s column1.txt column2.txt | grep -F '<' | cut -f1 -d"<" > c12diff.txt
sed -n 1'p' c12diff.txt | sed 's/ *$//g' | tr -d '\n' | tr -d '\t'
Cela supprime les espaces de fin et autres caractères invisibles.
Utilisation:
trim() {
local orig="$1"
local trmd=""
while true;
do
trmd="${orig#[[:space:]]}"
trmd="${trmd%[[:space:]]}"
test "$trmd" = "$orig" && break
orig="$trmd"
done
printf -- '%s\n' "$trmd"
}
Test unitaire (pour examen manuel):
#!/bin/bash
. trim.sh
enum() {
echo " a b c"
echo "a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a N b c "
echo "N a N b c "
echo " Na b c "
echo " a b c N "
echo " a b c N"
}
xcheck() {
local testln result
while IFS='' read testln;
do
testln=$(tr N '\n' <<<"$testln")
echo ": ~~~~~~~~~~~~~~~~~~~~~~~~~ :" >&2
result="$(trim "$testln")"
echo "testln='$testln'" >&2
echo "result='$result'" >&2
done
}
enum | xcheck
J'ai créé les fonctions suivantes. Je ne sais pas trop à quel point printf est portable, mais la beauté de cette solution est que vous pouvez spécifier exactement ce qu'est un "espace blanc" en ajoutant plus de codes de caractères.
iswhitespace()
{
n=`printf "%d\n" "'$1'"`
if (( $n != "13" )) && (( $n != "10" )) && (( $n != "32" )) && (( $n != "92" )) && (( $n != "110" )) && (( $n != "114" )); then
return 0
fi
return 1
}
trim()
{
i=0
str="$1"
while (( i < ${#1} ))
do
char=${1:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
str="${str:$i}"
i=${#1}
fi
(( i += 1 ))
done
i=${#str}
while (( i > "0" ))
do
(( i -= 1 ))
char=${str:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
(( i += 1 ))
str="${str:0:$i}"
i=0
fi
done
echo "$str"
}
#Call it like so
mystring=`trim "$mystring"`
Supprimer des espaces dans un espace:
(text) | fmt -su
J'avais besoin de couper les espaces d'un script lorsque la variable IFS
était définie sur autre chose. S'appuyant sur Perl a fait le tour:
# trim() { echo $1; } # This doesn't seem to work, as it's affected by IFS
trim() { echo "$1" | Perl -p -e 's/^\s+|\s+$//g'; }
strings="after --> , <-- before, <-- both --> "
OLD_IFS=$IFS
IFS=","
for str in ${strings}; do
str=$(trim "${str}")
echo "str= '${str}'"
done
IFS=$OLD_IFS
var=" a b "
echo "$(set -f; echo $var)"
>a b
Utilisez ce simple Bash expansion des paramètres:
$ x=" a z e r ty "
$ echo "START[${x// /}]END"
START[azerty]END
Cette coupe plusieurs espaces de l'avant et la fin
whatever=${whatever%% *}
whatever=${whatever#* }
Encore une autre solution avec tests unitaires qui ajuste $IFS
à partir de stdin, et fonctionne avec tout séparateur d'entrée (même $'\0'
):
ltrim()
{
# Left-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local trimmed
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
printf "${1-\x00}"
trimmed=true
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
fi
}
rtrim()
{
# Right-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local previous last
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${previous+defined}" ]
then
printf %s "$previous"
printf "${1-\x00}"
fi
previous="$REPLY"
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
last="$REPLY"
printf %s "$previous"
if [ -n "${previous+defined}" ]
then
printf "${1-\x00}"
fi
else
last="$previous"
fi
right_whitespace="${last##*[!$IFS]}"
printf %s "${last%$right_whitespace}"
}
trim()
{
# Trim $IFS from individual lines
# $1: Line separator (default NUL)
ltrim ${1+"$@"} | rtrim ${1+"$@"}
}
Je devais tester le résultat (numérique) à partir d'une commande, mais il semblait que la variable avec le résultat contenait des espaces et des caractères non imprimables. Par conséquent, même après un "trim", la comparaison était erronée. Je l'ai résolu en extrayant la partie numérique de la variable:
numerical_var=$(echo ${var_with_result_from_command} | grep -o "[0-9]*")