Mój przykładowy ciąg jest następujący:
This is 02G05 a test string 20-Jul-2012
Teraz z powyższego ciągu chcę wyodrębnić 02G05
. W tym celu wypróbowałem następujące wyrażenie regularne z sed
$ echo "This is 02G05 a test string 20-Jul-2012" | sed -n '/\d+G\d+/p'
Ale powyższe polecenie nic nie drukuje i uważam, że nie jest w stanie dopasować niczego do wzorca, który dostarczyłem sedowi.
Więc moje pytanie brzmi: co robię źle i jak to poprawić.
Kiedy próbuję powyższego ciągu i wzoru w Pythonie, otrzymuję wynik
>>> re.findall(r'\d+G\d+',st)
['02G05']
>>>
sed
. Ich smaki regex są zupełnie inne.Odpowiedzi:
Wzorzec
\d
może nie być obsługiwany przezsed
. Spróbuj[0-9]
lub[[:digit:]]
zamiast tego.Aby wydrukować tylko rzeczywiste dopasowanie (a nie całą pasującą linię), użyj podstawienia.
sed -n 's/.*\([0-9][0-9]*G[0-9][0-9]*\).*/\1/p'
źródło
.*
jest to konieczne z twoim wyrażeniem regularnym, ponieważ kiedy próbujęsed -n 's/\([0-9]\+G[0-9]\+\)/\1/p'
, po prostu drukuje cały wiersz.2G05
nie drukuje02G05
. Wyrażenie, które działa, to's/.*\([0-9][0-9]G[0-9][0-9]*\).*/\1/p'
sed -n 's/\(.*[^0-9]\)\?\([0-9][0-9]*G[0-9][0-9]*\).*/\2/p'
byłoby bardziej ogólne. (Zakładam swojesed
wsporniki\?
do zera lub jednego wystąpienia.)\w
,\s
itpA co powiesz na używanie
grep -E
?echo "This is 02G05 a test string 20-Jul-2012" | grep -Eo '[0-9]+G[0-9]+'
źródło
sed
Można by opracować złożony scenariusz dla tego przypadku, ale po co się tym przejmować?egrep
używa rozszerzonego wyrażenia regularnegosed
igrep
używa standardowego wyrażenia regularnegoegrep
lubgrep -e
lubsed -E
rozszerzonego wyrażenia regularnego, a kod Pythona w pytaniu używa PCRE, (typowe wyrażenie regularne perla) GNU grep może używać PCRE z-P
opcją.egrep
lubgrep -E
lubsed -r
grep
musi-m 1
się zatrzymać po pierwszym meczu.sed
nie rozpoznaje\d
, użyj[[:digit:]]
zamiast tego. Będziesz także musiał uciec+
lub użyć-r
przełącznika (-E
na OS X).Zauważ, że
[0-9]
działa to również w przypadku cyfr arabsko-hinduskich.źródło
sed -n '/[0-9]\+G[0-9]\+/p'
. Teraz po prostu drukuje cały ciągSpróbuj tego zamiast tego:
echo "This is 02G05 a test string 20-Jul-2012" | sed 's/.* \([0-9]\+G[0-9]\+\) .*/\1/'
Ale zwróć uwagę, że jeśli w jednym wierszu znajdują się dwa wzory, drukuje drugi.
źródło
Spróbuj użyć rextract . Pozwoli ci to wyodrębnić tekst za pomocą wyrażenia regularnego i sformatować go.
Przykład:
$ echo "This is 02G05 a test string 20-Jul-2012" | ./rextract '([\d]+G[\d]+)' '${1}' 2G05
źródło
\d
są całkowicie zbędne.