2016-04-05 15 views
-4

telefon numara biçimini 999-999-9999 - (999)999-9999) değiştirmek için bir sed komutu gerekiyor. İşte Ben çalışıyorum budur:Telefon numarası biçimini 999-999-9999'dan (999)999-9999

sed 's/[[:digit:]]\-[[:digit:]]\-[[:digit:]]/\([[:digit:]]\)[[:digit:]]\-[[:digit:]]/gp' 

Ben de denedim bu:

sed 's/([0-9]{3})\-([0-9]{3})\-([0-9]{4})/\(([0-9]{3}\))([0-9]{3})\-([0-9]{4})/gp' 
+0

[[: digit:]] 'birimleri tek basamaklı, üçlü basamaklarla eşleşmiyor. –

cevap

2

[[:digit:]] tek rakamla eşleşir notasyonu; Yinelenen rakamları eşleştirmeniz gerekir, \{3\} numaralı tekrar sayımını (sabit bir sayım için; sayılan sayım aralıkları da vardır, ancak bunlar burada alakalı değildir ve * vb.) tekrarlanan rakamlarla eşleşmeniz gerekir. Ayrıca, \(…\)'da neleri eşleştirdiğinize dikkat etmeniz gerekir; Değiştirmede, yakalanan parçalara başvurmak için \1 vb. Kullanırsınız. Yakalar, \( sembollerinin sırasına göre soldan sağa numaralandırılır.

sed 's/\([[:digit:]]\{3\}\)-\([[:digit:]]\{3\}-[[:digit:]]\{4\}\)/(\1)\2/g' 

Veya:

sed 's/\([0-9]\{3\}\)-\([0-9]\{3\}-[0-9]\{4\}\)/(\1)\2/g' 

Bu klasik sed nottur; Çok genişletilmiş normal ifadeler kullanarak varyantları bulabilirsiniz, ancak bu gösterimin aksine, platforma bağlı olarak farklı seçeneklere ihtiyacınız vardır. Modeller 3 rakam (ilk yakalama), bir tire, sonra 3 daha fazla rakam, bir başka çizgi ve ikinci yakalama olarak 4 basamak ararlar ve tüm bunları açık ayraçla (Amerikan parantezi), ilk 3 rakam, yakın ayraçla değiştirirler. ve kalan 3 rakam, tire, 4 basamak.

BSD (Mac OS X):

sed -E 's/([0-9]{3})-([0-9]{3}-[0-9]{4})/(\1)\2/g' 

GNU:

sed -r 's/([0-9]{3})-([0-9]{3}-[0-9]{4})/(\1)\2/g' 

Not bu normal ifadelerin hepsi dönüştürmek olacağını

9876-345-54321 

için:

9(876)345-54321 

Bu, özellikle sed’da daha az önemsiz olanı düzeltmek. Perl kullanarak:

$ echo "987-654-3210 and 2987-654-and 222-333-4444 and 543-432-5544" | 
> perl -p -e 's/\b([0-9]{3})-([0-9]{3}-[0-9]{4})\b/(\1)\2/g' 
(987)654-3210 and 2987-654-and (222)333-4444 and (543)432-5544 
$ 

\b işaretleri PCRE'nin bir kelime sınırı. Bu, a222-333-4444'un Perl tarafından eşleşmediği anlamına gelir; Eşleşmeyen dizgeden önce, basamaksız veya dize başlangıcında ve basamaksız veya dize bitiminde ısrar etmek için işleri hassaslaştırabilirsiniz.

$ echo "987-654-3210 and 2987-654-and a222-333-4444 and 543-432-5544" | 
> perl -p -e 's/(^|\D)([0-9]{3})-([0-9]{3}-[0-9]{4})(\D|$)/\1(\2)\3\4/g' 
(987)654-3210 and 2987-654-and a(222)333-4444 and (543)432-5544 
$ 

Ya (BSD veya GNU) ile

sed genişletilmiş düzenli ifadeler (BSD gösteriliyor): İsterseniz reddedildiği haneli karakter sınıfı notasyonu [^[:digit:]] yazılabilir olduğunu

$ echo "987-654-3210 and 2987-654-and a222-333-4444 and 543-432-5544" | 
> sed -E 's/(^|[^0-9])([0-9]{3})-([0-9]{3}-[0-9]{4})([^0-9]|$)/\1(\2)\3\4/g' 
(987)654-3210 and 2987-654-and a(222)333-4444 and (543)432-5544 
$ 

Not.

Yinelemeli geliştirme yardımcı olur.

+0

Harika, teşekkürler! Bu parçanın tam olarak ne yaptığını açıklayabilir misiniz, (\ 1) \ 2 /? – Edwin

+0

İlk varyasyonda, '\ (… \)' 'eşleştirilenin bir kısmını' yakalar '. Yerine koyma sırasında, parçalara atıfta bulunmak için, yakalanan fragmanlara gerektiği gibi (burada, her defasında bir kez) '\ 1' vb. Parçacıklar, '\ ('sembollerinin göründüğü sırayla indekslenir. Yani, (\ 1) \ 2', basamaklı çizgi dizgisini açık bir ayraçla, ilk 3 basamaklı grupla, bir yakın ayraçla değiştirir ve ikinci yakalanan dize (999-9999) –

+0

Tüm yardımlarınız için teşekkürler! – Edwin

1
$ echo 123-456-7890 | sed -r 's/([0-9]{3})-([0-9]{3}-[0-9]{4})/(\1)\2/' 
(123)456-7890 
+1

Neden awk' kullanmıyorsunuz? – hek2mgl

+0

@ hek2mgl: Çünkü soru “sed” (etiketle ve neyin denendiğini göstererek) soruyor. Burada büyük bir avantaj sağlayan awk göremiyorum; 'gsub' veya eşdeğerinin kullanılması olanaklıdır, ancak eğer bir şey varsa, gösterim“ sed' ”den daha sessizdir. –

+0

Sanırım bir şakaydı. – karakfa

İlgili konular