Creo que se puede hacer esto con solo grep
, sort
y tail
así. Aquí hay algunos ejemplos de cadenas.
$ echo <str> | grep -oP "\d+" | sort -n | tail -1
¿Dónde <str>
está nuestra cadena en cuestión?
Ejemplo
$ set -o posix; set | grep "str[0-9]"
str0=212334123434test233
str1=212334123434test233abc44
str2=233test212334123434
str3=a212334123434test233abc44
str4=a91234b212334123434abc
Ahora si ejecuto estos a través de mi grep ...
comando a su vez.
$ 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
Este enfoque funciona seleccionando todas las subcadenas que son secuencias de dígitos. Luego ordenamos esta salida numéricamente, sort -n
y luego tomamos el último valor de la lista, usando tail -1
. Esta será la subcadena más larga.
Puede ver cómo funciona tail -1
despegando y volviendo a ejecutar uno de los ejemplos:
$ echo $str4 | grep -oP "\d+" | sort -n
91234
212334123434
Cadenas que comienzan con ceros
El enfoque anterior funciona para todas las situaciones que podría concebir, excepto una. @terdon mencionó en el chat este escenario que frustra el enfoque anterior.
Entonces, para lidiar con esto, deberá cambiar ligeramente las tácticas. El núcleo del enfoque anterior todavía se puede aprovechar, sin embargo, también debemos inyectar el número de caracteres en los resultados. Esto le da a la capacidad de ordenar los resultados por número de caracteres en las cadenas y sus valores.
$ 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
Resultados:
$ 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
Puede condensar esto un poco haciendo uso de la capacidad de Bash para determinar la longitud de una variable usando ${#var}
.
$ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001
Usando `grep -P
He optado por usarlo grep -P ...
anteriormente porque, como desarrollador de Perl, me gusta la sintaxis de clase de decir todos los dígitos de esta manera: en \d+
lugar de [[:digit:]]\+
o [0-9]\+
. Pero para este problema en particular no es realmente necesario. Podrías cambiar fácilmente el grep
que he usado así:
$ .... grep -o "[0-9]\+" ....
Por ejemplo:
$ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001