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 .

221
demandé sur JonyD 2010-07-02 03:29:38

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 ':'
 }
321
répondu Stephen 2010-07-02 00:05:40

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.

291
répondu a3nm 2013-01-31 20:22:20

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
62
répondu William Pursell 2012-05-02 11:59:44

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.

23
répondu Nicholas M T Elliott 2010-07-01 23:39:25

:

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]}
18
répondu Dennis Williamson 2010-07-02 00:13:27

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
5
répondu Rafael 2016-11-10 10:09:35
$ 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 .

5
répondu user3133260 2017-07-13 11:47:57

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 .

4
répondu Ab Irato 2017-11-24 22:48:11

Utilisant Bash.

$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo  $${#}
0
3
répondu ghostdog74 2017-04-27 22:10:55
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.

2
répondu Crytis 2017-06-07 09:12:43

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.

2
répondu 021 2018-08-22 13:35:36
for x in `echo $str | tr ";" "\n"`; do echo $x; done
1
répondu Nahid Akbar 2012-06-22 03:03:37

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.

1
répondu Christoph Böddeker 2018-02-19 15:50:21

une solution à l'aide de la lecture builtin

IFS=':' read -a field <<< "1:2:3:4:5"
echo ${field[4]}
0
répondu baz 2017-11-24 19:27:11