Wierzę, że można to zrobić tylko grep
, sort
i tail
jak dobrze. Oto kilka przykładowych ciągów.
$ echo <str> | grep -oP "\d+" | sort -n | tail -1
Gdzie <str>
jest kwestionowany nasz ciąg?
Przykład
$ set -o posix; set | grep "str[0-9]"
str0=212334123434test233
str1=212334123434test233abc44
str2=233test212334123434
str3=a212334123434test233abc44
str4=a91234b212334123434abc
Teraz, jeśli przejrzę je grep ...
kolejno po kolei.
$ 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
Takie podejście polega na wybraniu wszystkich podciągów, które są ciągami cyfr. Następnie sortujemy dane wyjściowe numerycznie, sort -n
a następnie pobieramy ostatnią wartość z listy za pomocą tail -1
. To będzie najdłuższy podciąg.
Możesz zobaczyć, jak to działa, tail -1
zdejmując i ponownie uruchamiając jeden z przykładów:
$ echo $str4 | grep -oP "\d+" | sort -n
91234
212334123434
Ciągi zaczynające się od zer
Powyższe podejście działa w każdej sytuacji, z wyjątkiem jednej. @terdon wspomniał na czacie o tym scenariuszu, który udaremnia powyższe podejście.
Aby sobie z tym poradzić, trzeba nieco zmienić taktykę. Jądro powyższego podejścia może być nadal wykorzystywane, jednak musimy również wprowadzić liczbę znaków do wyników. Daje to sortowi możliwość sortowania wyników według liczby znaków w łańcuchach i ich wartości.
$ 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
Wyniki:
$ 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
Możesz to trochę skondensować, wykorzystując zdolność Basha do określenia długości zmiennej za pomocą ${#var}
.
$ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001
Używanie `grep -P
Zdecydowałem się użyć grep -P ...
powyższego, ponieważ jako programista Perla podoba mi się składnia klasowa wypowiadania wszystkich cyfr w ten sposób: \d+
zamiast [[:digit:]]\+
lub [0-9]\+
. Ale w przypadku tego konkretnego problemu nie jest tak naprawdę potrzebny. Równie łatwo możesz wymienić grep
używane przeze mnie:
$ .... grep -o "[0-9]\+" ....
Na przykład:
$ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \
sort -n | tail -1 | cut -d" " -f2
0000000000001