Réponses:
Vous pouvez utiliser des opérateurs de chaîne :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
Cela coupe tout de l'avant jusqu'à un ':', avec avidité.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
${foo%:*}
. #
- Depuis le début; %
- de fin. #
, %
- correspondance la plus courte; ##
, %%
- match le plus long.
echo ${pwd##*/}
ne marche pas.
pwd
comme une variable. Essayez dir=$(pwd); echo ${dir##*/}
. Travaille pour moi!
Une autre façon consiste à inverser avant et après cut
:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
Cela permet d'obtenir très facilement le dernier mais un seul champ, ou toute plage de champs numérotés à partir de la fin.
echo "1 2 3 4" | rev | cut -d " " -f1 | rev
rev
, c'était juste ce dont j'avais besoin! cut -b20- | rev | cut -b10- | rev
Il est difficile d'obtenir le dernier champ en utilisant cut, mais voici quelques solutions dans awk et perl
echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
/
caractère de finition : /a/b/c/d
et /a/b/c/d/
donnent le même résultat ( d
) lors du traitement pwd | awk -F/ '{print $NF}'
. La réponse acceptée entraîne un résultat vide dans le cas de/a/b/c/d/
/
comme délimiteur, et si votre chemin est, /my/path/dir/
il utilisera la valeur après le dernier délimiteur, qui est simplement une chaîne vide. Il est donc préférable d'éviter la barre oblique si vous devez faire une chose comme moi.
awk '{$NF=""; print $0}' FS=: OFS=:
fonctionne souvent assez bien.
En supposant une utilisation assez simple (aucun échappement du délimiteur par exemple), vous pouvez utiliser grep:
$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5
Ventilation - recherchez tous les caractères et non le délimiteur ([^:]) à la fin de la ligne ($). -o imprime uniquement la pièce correspondante.
Une manière:
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]}
Utilisation d'expressions régulières Bash (version> = 3.2):
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ 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
.
\n
, mais dans la plupart des cas, c'est la solution la plus lisible.
En utilisant 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
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érifiez la manipulation des chaînes dans bash .
a
, pas le dernier champ .
Il y a beaucoup de bonnes réponses ici, mais je veux quand même partager celle-ci en utilisant le nom de base :
basename $(echo "a:b:c:d:e" | tr ':' '/')
Cependant, il échouera s'il y a déjà un '/' dans votre chaîne . Si slash / est votre délimiteur, il vous suffit (et devrait) utiliser le nom de base.
Ce n'est pas la meilleure réponse, mais cela montre simplement comment vous pouvez être créatif en utilisant les commandes bash.
Utilisation de Bash.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo \$${#}
0
echo ${!#}
au lieu de eval echo \$${#}
.
for x in `echo $str | tr ";" "\n"`; do echo $x; done
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.
Peut-être un peu tard avec la réponse, bien qu'une solution simple soit d'inverser l'ordre de la chaîne d'entrée. Cela vous permettrait de toujours gagner le dernier élément, quelle que soit sa longueur.
[chris@desktop bin]$ echo 1:2:3:4:5 | rev | cut -d: -f1
5
Il est important de noter cependant que si vous utilisez cette méthode et que les nombres sont supérieurs à 1 chiffre (ou supérieur à un caractère en toute circonstance), vous devrez exécuter une autre commande 'rev' sur la sortie canalisée.
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1
42
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1 | rev
24
J'espère que je peux vous aider
Si vous aimez python et avez une option pour installer un paquet, vous pouvez utiliser cet utilitaire python .
# install pythonp
pythonp -m pip install pythonp
echo "1:2:3:4:5" | pythonp "l.split(':')[-1]"
5
echo "1:2:3:4:5" | python -c "import sys; print(list(sys.stdin)[0].split(':')[-1])"
pythonp
package est de vous faire faire les mêmes choses python -c
qu'avec moins de saisies de caractères. Veuillez consulter le fichier README dans le référentiel.
5
si la chaîne l'est1:2:3:4:5:
(tout en utilisant les opérateurs de chaîne donne un résultat vide). Ceci est particulièrement pratique lors de l'analyse de chemins pouvant contenir (ou non) un/
caractère de fin .