Comment découper une chaîne en shell et obtenir le dernier champ
supposons que j'ai la chaîne de caractères 1:2:3:4:5
et que je veux obtenir son dernier champ ( 5
dans ce cas). Comment je fais ça avec Bash? J'ai essayé cut
, mais je ne sais pas comment spécifier le dernier champ avec -f
.
14 réponses
vous pouvez utiliser opérateurs de chaîne de caractères :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
cela atténue tout de l'avant jusqu'à un ':', avec gourmandise.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
une autre façon est de faire marche arrière avant et après cut
:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
cela rend très facile d'obtenir l'avant-dernier champ, ou n'importe quelle gamme de champs numérotés de la fin.
il est difficile d'obtenir le dernier champ en utilisant cut, Mais voici (un ensemble de) solutions dans awk et perl
$ echo 1:2:3:4:5 | awk -F: '{print $NF}' 5 $ echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]' 5
en supposant une utilisation assez simple( pas d'échappement du délimiteur, par exemple), vous pouvez utiliser grep:
$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5
Ventilation - trouver tous les caractères qui ne sont pas le délimiteur ([^:]) à la fin de la ligne ($). - o n'imprime que la partie correspondante.
:
var1="1:2:3:4:5"
var2=${var1##*:}
un autre, en utilisant un tableau:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}
encore un autre avec un tableau:
var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}
utilisant Bash (version > = 3.2) expressions régulières:
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
par sed
:
$ echo '1:2:3:4:5' | sed 's/.*://' # => 5
$ echo '' | sed 's/.*://' # => (empty)
$ echo ':' | sed 's/.*://' # => (empty)
$ echo ':b' | sed 's/.*://' # => b
$ echo '::c' | sed 's/.*://' # => c
$ echo 'a' | sed 's/.*://' # => a
$ echo 'a:' | sed 's/.*://' # => (empty)
$ echo 'a:b' | sed 's/.*://' # => b
$ echo 'a::c' | sed 's/.*://' # => c
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e
traduisez simplement le délimiteur en une nouvelle ligne et choisissez la dernière entrée avec tail -1
.
si votre dernier champ est un seul caractère, vous pouvez le faire:
a="1:2:3:4:5"
echo ${a: -1}
echo ${a:(-1)}
Vérifier de manipulation de chaîne en bash .
Utilisant Bash.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo $${#}
0
echo "a:b:c:d:e"|xargs -d : -n1|tail -1
de la Première utilisation xargs de la diviser à l'aide de ":",-n1 signifie que chaque ligne seulement une partie.Ensuite,pring la dernière partie.
il y a beaucoup de bonnes réponses ici, mais je veux quand même partager celui-ci en utilisant basename :
basename $(echo "a:b:c:d:e" | tr ':' '/')
mais il sera un échec si il y a déjà quelques '/' dans votre chaîne de caractères . Si slash / est votre délimiteur, alors vous n'avez qu'à (et devriez) utiliser basename.
ce n'est pas la meilleure réponse, mais elle montre simplement comment vous pouvez être créatif en utilisant des commandes bash.
pour ceux qui sont à l'aise avec Python, https://github.com/Russell91/pythonpy est un bon choix pour résoudre ce problème.
$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'
de l'aide pythonpy: -x treat each row of stdin as x
.
Avec cet outil, il est facile d'écrire du code python qui est appliqué à l'entrée.
une solution à l'aide de la lecture builtin
IFS=':' read -a field <<< "1:2:3:4:5"
echo ${field[4]}