Szukam metody wydrukowania najdłuższej liczby w ciągu.
Np .: jeśli mam ciąg
212334123434test233
jak mogę wydrukować
212334123434
?
Uwaga: szukam najdłuższej ciągłej sekwencji liczb, a nie liczbowo wyższej wartości.
Edycja: Dziękujemy za odpowiedzi, wszyscy. Odpowiedź na to pytanie była przytłaczająca. Oznacziłem post @ HaukeLaging jako zaakceptowaną odpowiedź, ponieważ bardzo dobrze pasował do mojego konkretnego przypadku, ale chciałbym zauważyć, że wszystkie odpowiedzi są jednakowo prawidłowe. Zawsze świetnie jest mieć kilka różnych opcji rozwiązania problemu.
text-processing
sed
awk
Glutanimate
źródło
źródło
Odpowiedzi:
źródło
Wierzę, że można to zrobić tylko
grep
,sort
itail
jak dobrze. Oto kilka przykładowych ciągów.Gdzie
<str>
jest kwestionowany nasz ciąg?Przykład
Teraz, jeśli przejrzę je
grep ...
kolejno po kolei.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: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.
Wyniki:
Możesz to trochę skondensować, wykorzystując zdolność Basha do określenia długości zmiennej za pomocą
${#var}
.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:Na przykład:
źródło
${#i}
do uzyskania długości łańcucha może zaoszczędzić ci dzwonieniawc
, jeśli chcesz przejść do konkretnej bashgrep -o "[0-9]\+"
zamiastgrep -oP "\d+"
Rozwiązanie w
perl
:Bibliografia
źródło
Za pomocą python z ciągiem przekazanym w wierszu polecenia i zakładając, że chcesz pierwszą sekwencję o maksymalnej długości:
źródło
python -c "import re,sys; print max(re.split(r'\D+', sys.argv[1]), key=len)"
Oto inne podejście Perla, które może radzić sobie zarówno z liczbami dziesiętnymi, jak i liczbami całkowitymi:
Zauważ, że żadna z dotychczas opublikowanych odpowiedzi nie dotyczy miejsc po przecinku, a ponieważ określasz, że chcesz mieć najdłuższą, a nie największą liczbowo liczbę, zakładam, że faktycznie potrzebujesz miejsc po przecinku.
Wyjaśnienie
perl -lne
:-n
Oznacza „czytaj wiersz po wierszu i uruchom podany przez-e
niego skrypt ”.-l
Dodaje nowej linii do każdegoprint
połączenia (i innych rzeczy nie istotnych tutaj).while(/([\d.]+)/g)
: iteruj po wszystkich liczbach (\d
oznacza to[0-9]
,[\d.]
że dopasują cyfry i.
. Jeśli chcesz również znaleźć liczby ujemne, dodaj-
. Nawiasy przechwytują dopasowany ciąg znaków,$1
który jest używany w następnym kroku.$max=$1 if length($1) > length($max)
: Jeśli długość bieżącego dopasowania jest większa niż najdłuższa jak dotąd ($max
), zapisz dopasowanie jako$max
.print $max
: wydrukuj najdłuższy ciąg znalezionych liczb. Zostanie to wykonane po zakończeniu pętli while, a więc po znalezieniu wszystkich liczb.źródło
\D(\d+(?:\.\d+)?)\D
Zamiast tego proponuję coś takiego .\D
kotwic ....
jak w adresach IP.Dany
następnie w bash
Prawdopodobnie czystsze rozwiązanie bash wykorzystujące tablicę skonstruowaną przez zastąpienie znaków innych niż ciąg znaków spacją zamiast grep
źródło
Opierając się na odpowiedzi z @mikeserv, oto kolejna alternatywa. Wyodrębnia liczby (według metody Mikeserva), a następnie sortuje je w kolejności numerycznej i przyjmuje ostatnią. Pomijając zera wiodące, otrzymasz największą liczbę (nie uwzględniając znaku):
źródło
set -- $(echo $str | tr ... ) ; b=${#1} ; for d ; do [ ${#d} -gt $b ] && b=${#d} n=$d ; done ; echo $n
tr
, nie zrażę się, jeśli zastosujesz powyższe. Prawdopodobniesort
jest szybszy, ale z drugiej strony czeka na zakończenie strumienia tak samo jak$(subshell)
. Nie wiem W każdym razie twoja jest już doskonałą odpowiedzią, ale jeśli masz ochotę dodać powyższą pętlę powłoki, nie krępuj się, to wszystko co mówię. A tak przy okazji - możliwe jest, żesort
obejdzie się to bez odrobiny kreatywnej obsługiwc -L
itee
transmisji… Skończyłem z tym pytaniem - jestem zawstydzony.tr
z podpowłoki i się go pozbyćprintf
. Po prostu zrób'0-9' '\n'
.sortowanie bash i GNU
źródło
Użyj znaków nienumerycznych, aby podzielić ciąg i znajdź najdłuższą sekwencję lub największą wartość liczbową (dla liczb o równej długości) za pomocą operatora trójskładnikowego.
Możesz także ustawić separator rekordów awk (
RS
) na dowolny ciąg znaków nienumeryczny:źródło
RS = '[^0-9]+'
i użyć wewnętrznej pętli Awk?echo "212334123434test233" | awk -v RS='[^0-9]+' 'length(longest) < length($0) {longest = $0};END{print longest}' 212334123434
RS
zmiennej, muszę przyznać, że widzę ją po raz pierwszy. Masz więcej wskazówek do zaoferowaniaawk
niż ja hahaha!