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 grep
bireyin -o
bayrağı. 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, -e
birden ç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 .
file
Ayrı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 -E
anlatmak için bayrak grep
genişletilmiş normal ifade kullanma. Sözdizimi (pattern1|pattern2)
- bu pattern1
ve / 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ı -P
istemek grep
iç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 sed
anlar -E
aynı anlama gelen)
s/old/new/
yerine old
sahipnew
(pattern)
veya vb. pattern
ile 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
\2
sed
.
bu nedenle herhangi bir karakteri .*
temsil eder.
;
kabukta olduğu gibi komutları ayırır.