2009-11-15 7 views
9

Biorąc pod uwagę wejścieDlaczego `grep -o` kończy się niepowodzeniem i jak powinienem obejść go?

echo abc123def | grep -o '[0-9]*' 

na jednym komputerze (z GNU grep 2.5.4), to zwraca 123, a na inny (z GNU grep 2.5.1) zwraca pusty ciąg. Czy jest jakieś wyjaśnienie, dlaczego grep 2.5.1 nie działa tutaj, czy jest to po prostu błąd? Używam w ten sposób grep -o w skrypcie bash, który chciałbym móc uruchomić na różnych komputerach (które mogą mieć różne wersje grep). Czy istnieje "właściwy sposób", aby uzyskać spójne zachowanie?

+1

Dlaczego chciałbyś skorzystać z wyrażenia regularnego, które może pasować do znaków zerowych? Spodziewam się, że pasuje do każdej linii, a nie tylko linii z cyframi. –

Odpowiedz

9

Tak, 2.5.1 za -o obsługa była buggy: http://www.mail-archive.com/[email protected]/msg00993.html

Grep prawdopodobnie nie jest odpowiednim narzędziem do tego przeznaczonych; sed lub tr lub nawet perl może być lepiej w zależności od rzeczywistego zadania.

+0

+1: Ale jeśli istnieje różnica pomiędzy małymi wersjami GNU 'grep' (choć z powodu błędów), nie ma dużej szansy na znalezienie spójności między różnymi komputerami. Istnieje jednak wiele innych narzędzi. – pavium

+1

Polecenie użycia innego narzędzia, bez prawidłowego rozwiązania, nie jest dobrą odpowiedzią. Jako dowód, w większości przypadków można go rozwiązać za pomocą czystego basha. Nie zawierałeś dla mnie dokładnego rozwiązania. – kisp

0

To daje podobne wyniki:

echo abc123def | sed -n 's/[^0-9]*\([0-9]\+\).*/\1/p' 

Twoje pytanie jest niemal kopią this one.

2

możesz użyć powłoki. jej szybciej

$ str=abc123def 
$ echo ${str//[a-z]/} 
123 
2

miałem ten sam problem i okazało się, że egrep został zainstalowany na tym komputerze. Szybkie rozwiązanie używał

echo abc123def | egrep -o '[0-9]*' 
-1

Ponieważ używasz regex więc trzeba użyć albo:

  1. grep -E
  2. egrep (jak Sebastian pisał).

Powodzenia!

+2

-E/egrep jest wymagane dla * rozszerzonych * wyrażeń regularnych; "[0-9] *" jest prawidłowym podstawowym wyrażeniem regularnym. ("Re" w "grep" oznacza wyrażenie regularne). Być może błąd w wersji 2.5.1 nie był obecny w rozszerzonej obsłudze wyrażenia regularnego, ale sam fakt, że używane jest wyrażenie regularne, nie oznacza, że ​​potrzebujesz -E. – chepner

Powiązane problemy