Je crois que vous pouvez le faire avec juste grep
, sort
et tail
aussi bien. Voici quelques exemples de chaînes.
$ echo <str> | grep -oP "\d+" | sort -n | tail -1
Où <str>
est notre chaîne en question.
Exemple
$ set -o posix; set | grep "str[0-9]"
str0=212334123434test233
str1=212334123434test233abc44
str2=233test212334123434
str3=a212334123434test233abc44
str4=a91234b212334123434abc
Maintenant, si je les exécute grep ...
à tour de rôle via ma commande.
$ echo $str0 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str1 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str2 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str3 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str4 | grep -oP "\d+" | sort -n | tail -1
212334123434
Cette approche fonctionne en sélectionnant toutes les sous-chaînes qui sont des séquences de chiffres. Nous trions ensuite cette sortie numériquement, sort -n
puis récupérons la dernière valeur de la liste à l'aide de tail -1
. Ce sera la sous-chaîne la plus longue.
Vous pouvez voir comment cela fonctionne en retirant tail -1
et en réexécutant l'un des exemples:
$ echo $str4 | grep -oP "\d+" | sort -n
91234
212334123434
Chaînes commençant par des zéros
L'approche ci-dessus fonctionne pour toutes les situations que je pourrais concevoir sauf une. @terdon a mentionné dans le chat ce scénario qui déjoue l'approche ci-dessus.
Donc, pour y faire face, vous devrez légèrement changer de tactique. Le noyau de l'approche ci-dessus peut encore être exploité, mais nous devons également injecter le nombre de caractères dans les résultats. Cela donne à tri la possibilité de trier les résultats par nombre de caractères dans les chaînes et leurs valeurs.
$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2
Résultats:
$ echo $str0
0000000000001a2test
$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2
0000000000001
Vous pouvez condenser cela un peu en utilisant la capacité de Bash à déterminer la longueur d'une variable à l'aide ${#var}
.
$ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001
Utilisation de `grep -P
J'ai choisi d'utiliser grep -P ...
ci-dessus parce que moi, étant un développeur Perl, j'aime la syntaxe de classe de dire tous les chiffres comme ceci:, \d+
au lieu de [[:digit:]]\+
ou [0-9]\+
. Mais pour ce problème particulier, il n'est pas vraiment nécessaire. Vous pouvez tout aussi facilement échanger celui grep
que j'ai utilisé comme ceci:
$ .... grep -o "[0-9]\+" ....
Par exemple:
$ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001