Sed kullanarak bir dizeden metin nasıl çıkarılır?


98

Örnek dizem aşağıdaki gibidir:

This is 02G05 a test string 20-Jul-2012

Şimdi yukarıdaki dizeden çıkarmak istiyorum 02G05. Bunun için sed ile aşağıdaki regex'i denedim

$ echo "This is 02G05 a test string 20-Jul-2012" | sed -n '/\d+G\d+/p'

Ancak yukarıdaki komut hiçbir şey yazdırmıyor ve inandığım neden, sed için sağladığım modelle hiçbir şeyi eşleştiremiyor.

Öyleyse sorum şu ki burada neyi yanlış yapıyorum ve bunu nasıl düzelteceğim.

Yukarıdaki dize ve kalıbı python ile denediğimde sonucumu alıyorum

>>> re.findall(r'\d+G\d+',st)
['02G05']
>>>

6
Python kesinlikle değil sed. Normal ifade çeşitleri oldukça farklıdır.
üçlü

Yanıtlar:


99

Desen \d, sizin tarafınızdan desteklenmiyor olabilir sed. Deneyin [0-9]veya [[:digit:]]yerine.

Yalnızca gerçek eşleşmeyi yazdırmak için (eşleşen satırın tamamını değil), bir değişiklik kullanın.

sed -n 's/.*\([0-9][0-9]*G[0-9][0-9]*\).*/\1/p'

6
Teşekkürler iyi çalıştı. Ancak .*normal ifadenizle neden gerekli olduğuna dair bir sorum var çünkü denediğimde sed -n 's/\([0-9]\+G[0-9]\+\)/\1/p'tüm satırı yazdırıyor.
RanRag

7
Bu yüzden değil mi? Maçtan önce ve sonra gelenleri norhing ile değiştirin, ardından tüm satırı yazdırın.
üçlü

1
@tripleee Bu yalnızca yazdırır 2G05 değil 02G05. 's/.*\([0-9][0-9]G[0-9][0-9]*\).*/\1/p'
İşe yarayan

1
Bu, onu tam olarak iki haneye kodlar. sed -n 's/\(.*[^0-9]\)\?\([0-9][0-9]*G[0-9][0-9]*\).*/\2/p'Daha genel bir şey gibi bir şey . ( sedDesteklerinizi varsayıyorum\? Sıfır veya bir oluşum .)
2013

Ayrıca, aşağıdaki gibi çeşitli diğer yaygın Perl çıkışlarının nasıl değiştirileceğini öğrenmek için stackoverflow.com/a/48898886/874188 adresine de bakın.\w , \svb
tripleee

103

Kullanmaya ne dersin grep -E?

echo "This is 02G05 a test string 20-Jul-2012" | grep -Eo '[0-9]+G[0-9]+'

3
+1 Bu daha basittir ve aynı hat üzerindeki birden fazla eşleşme durumunu da doğru şekilde ele alır. Bu seddurum için karmaşık bir senaryo tasarlanabilir, ama neden zahmet edelim?
üçlü

egrepkullanımları Regexp'i genişletilmiş, sedve grepstandart Regexp'i kullanır egrepya grep -eya sed -Euzatılmış Regexp'i kullanın ve söz konusu piton kodu ile PCRE'yi kullanabilirsiniz (yaygın düzenli ifade perl), GNU grep PCRE'yi kullanır -Pseçeneği.
Felipe Buccioni

@FelipeBuccioni aslında olmalıdır egrepya grep -Eyased -r
SensorSmith

Tek bir (ilk) eşleşme için, '| kafa -1` (ters işaretler olmadan), bu yanıta göre başka bir soru.
SensorSmith

1
grepsahip -m 1ilk eşleşmeden sonra durdurmak için.
üçlü


5

Bunun yerine şunu deneyin:

echo "This is 02G05 a test string 20-Jul-2012" | sed 's/.* \([0-9]\+G[0-9]\+\) .*/\1/'

Ancak, bir satırda iki desen varsa, bunun 2.'yi yazdıracağını unutmayın.


Veya daha genel olarak birden fazla eşleşme varsa sonuncusu.
üçlü

0

Geri çekmeyi kullanmayı deneyin . Normal bir ifade kullanarak metni çıkarmanıza ve yeniden biçimlendirmenize izin verir.

Misal:

$ echo "This is 02G05 a test string 20-Jul-2012" | ./rextract '([\d]+G[\d]+)' '${1}'

2G05

Bu standart normal ifadeyi kullanıyorsa, etrafındaki köşeli parantezler \dtamamen gereksizdir.
2019, 06:16
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.