Bir dize etrafındaki açılış ve kapanış köşeli parantezleri kaldırmak için sed kullanma


19

Bu komutu Ubuntu 12.04.1 LTS'de bir bash kabuğunda çalıştırıyorum. Her iki kaldırmak çalışılıyor [ve ]sed ikinci zamana boruya gerek kalmadan tek bir hamlede, yani karakterleri.

Köşeli parantezlerin normal ifadede özel bir anlamı olduğunu biliyorum, bu yüzden ters eğik çizgi ile başlayarak onlardan kaçıyorum. Beklediğim sonuç sadece dize 123ama köşeli parantezler kaldı ve nedenini bilmek isterim!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]

Nihayetinde elde etmeye çalıştığım şey, köşeli parantezler arasında ne varsa, bash betiğimin başka bir yerinde kullanmak için bir bash değişkenine atamaktır, bu yüzden bunu başarmanın daha iyi bir yolu varsa (awk kullanarak, belki?), Lütfen bana bildirin .
Xhantar

2
Sadece bir yorum olarak eklemek: bash'ın PE özelliğini şu şekilde kullanabilirsiniz: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Valentin Bajrami

1
@ val0x00ff - Saf bash yerine koyma .. teşekkürler! :) Yeni bir şey öğrendim.
Ocak'ta Xhantar

Yanıtlar:


25

Kılavuzu dikkatlice izlerseniz bu kolaydır : bir karakter sınıfındaki tüm üyeler özel bir anlam kaybeder (birkaç istisna dışında). Ve] listede ilk sırada yer alıyorsa özel anlamını kaybeder . Deneyin:

$ echo '[123]' | sed 's/[][]//g'
123
$

Bu diyor ki:

  1. , dış [parantez], yani eklenen karakter, herhangi birinin yerini:
    • ] ve
    • [
  2. bunlardan herhangi birini boş dizeyle değiştirin - dolayısıyla boş yedek dizeyle //,
  3. onları her yerde değiştirin ( küresel olarak ) - dolayısıyla final g.

Yine, her dahil edildiğinde sınıfta bir ilk ] olmalıdır .


11

Neden işe yaramıyor emin değilim ama bu işe yarıyor:

echo '[123]' | sed 's/\(\[\|\]\)//g'

veya bu:

echo '[123]' | sed -r 's/(\[|\])//g'

Ayrıca farklı bir yaklaşım deneyebilir ve parantez içindeki dizeyi eşleştirebilirsiniz (dizenin kolayca eşleştirilebildiğini ve parantezler tarafından tanımlanmadığını varsayarak):

echo '[123]' | egrep -o "[0-9]+"

Orijinal regex kullanarak aynı sorunları yaşıyorum bu grepyüzden bu sadece bir sedşey değil şüpheli .

Tuhaf bir şekilde, bunlar farklı sonuçlar üretir, ancak bunlardan biri istediğinizle eşleşir:

echo '[123]' | egrep -o '[^][]+'
123

echo '[123]' | egrep -o '[^[]]+'
3]

Bunu orijinalinize uygulama sed(ve her iki köşeli parantezleri de/g kaldıracak şekilde değiştiriciyi ekleme ):

echo '[123]' | sed 's/[][]//g'
123

3. yaklaşımınız (egrep -o ...) sorunuma en temiz çözüm gibi görünüyor. Sadece köşeli parantezler arasında tamsayılarım olacak (ve üzgünüm, sorumu bundan bahsetmeliydim), bu yüzden bence herhangi bir tuhaflığa girmemeliydim. Teşekkürler!
Xhantar

3
Ayrıca şunları da kullanabilirsiniz tr: echo '[123]' | tr -d '[]'- kaçma ile ilgili karışıklıklardan kaçınır.
James O'Gorman

@James O'Gorman - İlginç. Nedense bunun trbir kerede en fazla bir karakter çevirebileceğini düşündüm ama yanılmışım. Teşekkürler!
Xhantar

4

Parantez öncesi ve sonrası her şeyi kaldırmak için:

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'
123

Verileriniz böyleyse, her zaman köşeli parantezlerle başlamak ve bitirmek anlamına gelir:

$ echo '[123]' | sed 's/.//;s/.$//;'
123

Üzerinde çalıştığım veriler her zaman bir köşeli parantez ile başlayıp bitecek. Yine de çözümümün neden çalışmadığını bilmek istiyorum. Herhangi bir fikir? Ve bunu 2x normal ifadelerini belirtmeden yapmanın bir yolu var mı?
Xhantar

1
@Guru bu çözüm benden çalıştı ve Xhantar'a gelince, Bu gerçekten geç bir cevap, ama kodunuzdan ve tldp.org'daki Bash Beginners rehberinden görebildiğim, bir tane için birden fazla arama yapmaya ve değiştirmeye çalışıyordunuz. '[' ve diğeri ']' için çalışmaz, iki farklı aramayı boşluk bırakmak ve değiştirmek için ";" veya -e seçenekleri. 's / <arama> / <değiştir> / g; s / <search> / <replace> / g 'OR sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar

1

'Abcdef [123] ghijk' gibi daha karmaşık bir dizeniz varsa, metni yalnızca köşeli parantezler arasında ayıklamak için dahili bash 'cut' komutunu da kullanabilirsiniz:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123

1

Tuşunu kullanarak açılış köşesinden kaçabilirsiniz \[. Kapatma braketi için kullanın []].

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.