Gösterdiğiniz dosyada tüm ayrıntılar tek bir satırda bulunur:
name : farah age : 23 phone number : 0123 education : degree
age :Komuta vb. Gibi sabit kodlama yapabileceğinizi varsaydım , ancak onu takip eden metin değişecektir ve ayrıntılar verilen sırada olmayabilir veya bitişik olmayabilir.
Sen doğrultusunda parçalarını ayıklamak grepbireyin -obayrağı. Bu, tüm satır yerine yalnızca eşleşen kısmı yazdırır.
age :Ve phone number :bölümlerini dahil etmek istiyorsanız, -ebirden çok eşleşme belirtmek için bayrağı veya alternatifi kullanabilirsiniz.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
İfade [^ ]*, boşluk olmayan herhangi bir sayıda karakter anlamına gelir, bu nedenle bir age :sonraki boşluğa kadar olan karakterlerle eşleşir .
fileAyrıntılarınızı içeren dosyanın adıyla değiştirin . Çıkışı >operatörle yeni bir dosyaya yeniden yönlendirerek şöyle yazabilirsiniz :
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Bunu yaptığınızda, herhangi bir çıktı görmezsiniz. Önce çıkışı kontrol etmeli, ardından yeniden yönlendirme eklemelisiniz.
İşte değişimli örnek. Biz kullanmak -Eanlatmak için bayrak grepgenişletilmiş normal ifade kullanma. Sözdizimi (pattern1|pattern2)- bu pattern1ve / veya eşleşir pattern2. İkisinden biri bulunursa, yazdırılır (diğerinin bulunup bulunmamasına bakılmaksızın). Şimdi +, önceki karakterin *sıfır veya daha fazla anlamı yerine önceki karakterlerden en az birinin anlamını kullanıyorum . Bu bağlamda, ikisi de eşit derecede iyi çalışır.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
age :Ve phone number:parçalarını atlamak istiyorsanız, Perl uyumlu normal ifadeleri kullanmayı -Pistemek grepiçin bayrağı kullanabilirsiniz. Bu, alternatifi ve ayrıca belirli bir kalıptan sonra metni eşleştirme yolunu destekler :
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Metni farklı biçimlendirmek istiyorsanız, sedörneğin şunları kullanabilirsiniz :
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Bu daha ageönce gelmeye bağlıdır phone number, bu yüzden durum böyle değilse ayarlayın. Siparişe güvenemezseniz, bu çok kıvrımlı komutu kullanabilirsiniz:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Bu, çizgiyi phone number :bölümün her satırda önce geleceği şekilde yeniden düzenler , ardından istenen ayrıntıları seçmek için ikinci bir değiştirme yapar. Burada kullanılan tekniği muru tarafından bu cevaba borçluyum .
sedÖnceki açıklamaların kapsamadığı komutlarla ilgili notlar
-r(GNU daha okunabilir komutlar için genişletilmiş düzenli ifade kullanmak sedanlar -Eaynı anlama gelen)
s/old/new/yerine oldsahipnew
(pattern)veya vb. patternile daha sonra başvurmak üzere kaydeder (yakalama gruplarının oluştuğu soldan sağa sıraya karşılık gelir - bunlardan yalnızca 7 tanesine kadar not alın !).\1\2sed
.bu nedenle herhangi bir karakteri .*temsil eder.
; kabukta olduğu gibi komutları ayırır.