Sed'de açgözlü olmayan (isteksiz) regex eşleşmesi?


406

Ben sadece etki alanı ayıklamak için URL satırlarını temizlemek için sed kullanmaya çalışıyorum.

Yani:

http://www.suepearson.co.uk/product/174/71/3816/

İstiyorum:

http://www.suepearson.co.uk/

(sonunda eğik çizgi olsun ya da olmasın, önemli değil)

Denedim:

 sed 's|\(http:\/\/.*?\/\).*|\1|'

ve (açgözlü olmayan niceleyiciden kaçmak)

sed 's|\(http:\/\/.*\?\/\).*|\1|'

ama açgözlü olmayan niceleyici ( ?) işe almak için görünmüyor , bu yüzden her zaman tüm dize eşleşen sona erer.


54
Bir yan not: Normal ifadelerinizi "|" ile sınırlandırırsanız, "/" lerden kaçmanıza gerek yoktur. Aslında, çoğu insan "|" "kazık çit" önlemek için "/" s yerine.
AttishOculus

12
@AttishOculus sed'deki yerine kullanılan bir ifadede 's' ifadesinden sonraki ilk karakter sınırlayıcıdır. Dolayısıyla 's ^ foo ^ bar ^' veya 's! Foo! Bar!' ayrıca çalışır
Squidly

1
Genişletilmiş normal ifade için kullanın sed -E 's.... Yine de isteksiz bir operatör yok.
Ondra Žižka

Soru başlığına cevap değil, bu özel durumda basit cut -d'/' -f1-3işler.
Petr Javorik

Yanıtlar:


421

Ne temel ne de genişletilmiş Posix / GNU normal ifadesi, açgözlü olmayan niceliği tanımıyor; daha sonra normal bir regex'e ihtiyacınız var. Neyse ki, bu bağlam için Perl regex'i elde etmek oldukça kolaydır:

perl -pe 's|(http://.*?/).*|\1|'

12
Yerinde yapmak için seçenekleri kullanın -pi -e.
reallynice

11
Kutsal sigaralar işe yaradığına inanamıyorum :-) Berbat olan tek şey artık senaryomun Perl bağımlılığı var :-( Artı tarafta, neredeyse her Linux dağıtımında Perl zaten çok büyük bir sorun değil :-)
Freedom_Ben

6
@Freedom_Ben: IIRC POSIX perliçin gereklidir
MestreLion

4
@ dolphus333: "Ne temel ne de genişletilmiş Posix / GNU regex açgözlü olmayan nicelik belirleyiciyi tanımıyor" "açgözlü olmayan niceleyiciyi kullanamayacağınız" anlamına gelir.
kaos

3
@ Sérgio istenen şeyi nasıl yaparsınız, ki bu imkansızdır sed, temel olarak sözdizimiyle aynıdırsed
chaos

250

Bu özel durumda, açgözlü olmayan bir normal ifadeyi kullanmadan işi yapabilirsiniz.

Bu sigara açgözlü regex deneyin [^/]*yerine .*?:

sed 's|\(http://[^/]*/\).*|\1|g'

3
Bu tekniği kullanarak sed match non greedy nasıl ifade edilir?
user3694243

6
Ne yazık ki yapamazsınız; kaosun cevabına bakınız .
Daniel H

Çok teşekkürler ... perl artık birçok linux dağıtımında varsayılan kurulum üssünde olmadığı için!
st0ne


@DanielH Aslında istendiği gibi bu tekniği kullanarak ifadeleri açgözlülükle eşleştirmek mümkün değildir . Her iki deseni de yeterli hassasiyetle yazmak biraz acı alabilir. Örneğin, bir URL'nin sorgusundaki bir anahtar / değer atamasını ayrıştırırken, atamayı kullanarak aramak gerekebilir ([^&=#]+)=([^&#]*). Kesin olarak bu şekilde çalışmayan durumlar vardır, örneğin, ana makine parçası ve yol adı için URL'yi ayrılmanın isteğe bağlı olduğu varsayılan son eğik çizgi ile ayrıştırırken:^(http:\/\/.+?)/?$
Thomas Urban

121

Sed ile, genellikle ayırıcıya kadar ayırıcı dışında bir şey arayarak açgözlü olmayan arama uygularım:

echo "http://www.suon.co.uk/product/1/7/3/" | sed -n 's;\(http://[^/]*\)/.*;\1;p'

Çıktı:

http://www.suon.co.uk

bu:

  • çıktı alma -n
  • arama, desen eşleme, değiştirme ve yazdırma s/<pattern>/<replace>/p
  • ;yerine arama komutu ayırıcısını kullan/ bu yüzden yazmak için daha kolay hale getirmek içins;<pattern>;<replace>;p
  • parantez maçı hatırlamak \(... \)ile sonradan erişilebilir \1,\2 ...
  • eşleşme http://
  • Parantez içindeki herhangi bir şey tarafından takip [], [ab/]anlamına geleceğini ya aya bya/
  • İlk ^olarak []vasıtasıylanot , yani herhangi bir şey tarafından takip ama şey[]
  • yani şu [^/]anlama gelir/ karakter
  • *böylece önceki gruba tekrar etmektir [^/]*hariç araçlar karakterler/ .
  • şimdiye kadar sed -n 's;\(http://[^/]*\)arama ve hatırlama ve http://ardından gelen karakterler hariç/ ne bulduğunuz
  • alan adının sonuna kadar arama yapmak istiyoruz, bu yüzden bir sonrakinde durun , sonuna bir tane /daha ekleyin /:sed -n 's;\(http://[^/]*\)/' ancak alan adından sonra satırın geri kalanıyla eşleşmek istiyoruz..*
  • şimdi grup 1 ( \1) 'de hatırlanan eşleşme alan adıdır, bu nedenle eşleşen satırı grupta kayıtlı öğelerle değiştirin \1ve yazdırın:sed -n 's;\(http://[^/]*\)/.*;\1;p'

Alan adından sonra ters eğik çizgi eklemek isterseniz, hatırlamak için gruba bir ters eğik çizgi ekleyin:

echo "http://www.suon.co.uk/product/1/7/3/" | sed -n 's;\(http://[^/]*/\).*;\1;p'

çıktı:

http://www.suon.co.uk/

8
Son düzenlemelere ilişkin olarak: Parantezler bir tür basamaklama karakteri olduğundan, özellikle yazarın yaptığı gibi, kelimeyi gerçek karakterlerle takip ederseniz, köşeli ayraç olarak adlandırmak yanlış değildir. Ayrıca, bazı kültürlerde tercih edilen kullanımdır, bu yüzden onu kendi kültürünüzde tercih edilen kullanımla değiştirmek biraz kaba görünmektedir, ancak editörün amaçladığı bu olmadığından eminim. Şahsen, yuvarlak parantez , köşeli parantez ve açılı parantez gibi tamamen açıklayıcı isimler kullanmak en iyisidir .
Alan Moore

2
Ayırıcıyı bir dizeyle değiştirmek mümkün müdür?
Matematik

37

sed "açgözlü olmayan" operatörü desteklemez.

"/" Eşleşmesini hariç tutmak için "[]" operatörünü kullanmanız gerekir.

sed 's,\(http://[^/]*\)/.*,\1,'

PS "/" ters eğik çizgi gerekmez.


pek sayılmaz. sınırlayıcı birçok olası karakterden biri olabilirse (yalnızca bir sayı dizisi söyleyin), olumsuzlama eşleşmeniz gittikçe karmaşıklaşabilir. bu iyi ama kesinlikle yapmak için bir seçenek olması güzel olurdu. * non greedy
gesell

1
Soru daha geneldi. Bu çözümler URL'ler için çalışır, ancak (örneğin) sondaki sıfırları sıyırma durumumda işe yaramaz. s/([[:digit:]]\.[[1-9]]*)0*/\1/Açıkçası iyi çalışmaz 1.20300. Orijinal soru URL'lerle ilgili olduğundan, kabul edilen cevapta bunlardan bahsedilmelidir.
Daniel H

33

Tembel (açgözlü olmayan) niceleyicinin simülasyonu sed

Ve diğer tüm normal tatlar!

  1. Bir ifadenin ilk oluşumunu bulma:

    • POSIX ERE ( -rseçenek kullanılarak )

      regex:

      (EXPRESSION).*|.

      sed:

      sed -r 's/(EXPRESSION).*|./\1/g' # Global `g` modifier should be on

      Örnek (ilk basamak dizisini bulma) Canlı demo :

      $ sed -r 's/([0-9]+).*|./\1/g' <<< 'foo 12 bar 34'
      12

      Nasıl çalışır ?

      Bu normal ifade bir dönüşümden yararlanır |. Her pozisyonda motor en uzun eşleşmeyi seçmeye çalışır (bu bir POSIX standardıdır ve bunu diğer birkaç motor takip eder), yani .bir eşleşme bulunana kadar devam eder ([0-9]+).*. Ancak düzen de önemlidir.

      resim açıklamasını buraya girin

      Global bayrak ayarlandığından, motor, giriş dizesinin sonuna veya hedefimize kadar karakter karakter eşleştirmeye devam etmeye çalışır. Değişimin sol tarafının ilk ve tek yakalama grubu eşleşir (EXPRESSION)kesilmez çizginin geri kalanı da hemen tüketilir .*. Şimdi ilk yakalama grubunda değerimizi koruyoruz.

    • POSIX BRE

      regex:

      \(\(\(EXPRESSION\).*\)*.\)*

      sed:

      sed 's/\(\(\(EXPRESSION\).*\)*.\)*/\3/'

      Örnek (ilk basamak dizisini bulma):

      $ sed 's/\(\(\([0-9]\{1,\}\).*\)*.\)*/\3/' <<< 'foo 12 bar 34'
      12

      Bu ERE versiyonu gibidir, ancak herhangi bir değişiklik söz konusu değildir. Bu kadar. Her bir pozisyonda motor bir rakamla eşleşmeye çalışır.

      resim açıklamasını buraya girin

      O bulunursa, diğer aşağıdaki basamak tüketilen ve yakalanır ve hattın geri kalan beri hemen aksi eşleştirilir olan *araçlar daha fazla veya sıfır bitti ikinci yakalama grubunu atlar \(\([0-9]\{1,\}\).*\)*ve bir nokta ulaşır. tek bir karakteri eşleştirmek için ve bu süreç devam eder.

  2. A'nın ilk oluşumunu bulma Sınırlandırılmış ifadenin :

    Bu yaklaşım, sınırlandırılmış bir dizenin ilk oluşumuyla eşleşecektir. Buna bir dize bloğu diyebiliriz.

    sed 's/\(END-DELIMITER-EXPRESSION\).*/\1/; \
         s/\(\(START-DELIMITER-EXPRESSION.*\)*.\)*/\1/g'

    Giriş dizesi:

    foobar start block #1 end barfoo start block #2 end

    -EDE: end

    -SDE: start

    $ sed 's/\(end\).*/\1/; s/\(\(start.*\)*.\)*/\1/g'

    Çıktı:

    start block #1 end

    İlk normal ifade, \(end\).*birinci uç sınırlayıcıyla eşleşir ve yakalar endve bunların tümü, son sınırlayıcı olan son yakalanan karakterlerle eşleşir. Bu aşamada bizim çıktısı: foobar start block #1 end.

    resim açıklamasını buraya girin

    Sonra sonuç \(\(start.*\)*.\)*yukarıdaki POSIX BRE sürümüyle aynı olan ikinci normal ifadeye aktarılır . Başlangıç ​​sınırlayıcı eşleşmezse tek bir karakterle starteşleşir, aksi takdirde başlangıç ​​sınırlayıcıyla eşleşir ve yakalar ve diğer karakterlerle eşleşir.

    resim açıklamasını buraya girin


Sorunuzu doğrudan cevaplama

Yaklaşım # 2'yi (sınırlandırılmış ifade) kullanarak iki uygun ifade seçmelisiniz:

  • EDE: [^:/]\/

  • SDE: http:

Kullanımı:

$ sed 's/\([^:/]\/\).*/\1/g; s/\(\(http:.*\)*.\)*/\1/' <<< 'http://www.suepearson.co.uk/product/174/71/3816/'

Çıktı:

http://www.suepearson.co.uk/

Not: Bu, aynı sınırlayıcılarla çalışmaz.


3) demo için regex101 gibi siteleri önerirken, sözdizimi ve özellik farklılıkları nedeniyle her zaman cli araçları için uygun olmadığını unutmayın
Sundeep

1
@Sundeep Teşekkürler. Tüm bu alıntıları tek tırnaklara çevirdim. Ayrıca en soldaki en uzun eşleşme kuralından bahsetmiştim. Ancak sedaynı standart düzeni izleyen diğer tüm motorlar eşitlik söz konusu olduğunda önemlidir. Yani echo 'foo 1' | sed -r 's/.|([0-9]+).*/\1/g'bir eşleşmesi echo 'foo 1' | sed -r 's/([0-9]+).*|./\1/g'yok ama var.
revo

@Sundeep ayrıca, sınırlandırılmış ifadeler için geçici bir çözüm, not eklediğim özdeş başlangıç ​​ve bitiş sınırlayıcıları için işe yaramadı .
revo

farklı konumlar aynı konumdan başladığında ve aynı uzunlukta olduğunda ne olduğu hakkında büyük bir nokta, diğer motorlar gibi sol-sağ sırayı takip edeceğini tahmin edin .. bu kılavuzda tarif edilirse bakmanız gerekir
Sundeep

burada garip bir durum var: stackoverflow.com/questions/59683820/…
Sundeep

20

Tek bir karakterden daha fazlası için açgözlü olmayan çözüm

Bu konu gerçekten eski ama insanların hala buna ihtiyacı olduğunu varsayıyorum. Diyelim ki ilk ortaya çıkana kadar her şeyi öldürmek istiyorsunuz HELLO. Söyleyemezsin [^HELLO]...

Yani güzel bir çözüm, girişte beklemediğiniz benzersiz bir kelimeyi yedekleyebileceğinizi varsayarak iki adımdan oluşur top_sekrit.

Bu durumda:

s/HELLO/top_sekrit/     #will only replace the very first occurrence
s/.*top_sekrit//        #kill everything till end of the first HELLO

Elbette, daha basit bir girişle daha küçük bir kelime, hatta tek bir karakter bile kullanabilirsiniz.

HTH!


4
Kullanılmayan karakteri bekleyemediğiniz durumlarda daha da iyi, kullanışlı hale getirmek için: 1. bu özel karakteri gerçekten kullanılmayan WORD ile değiştirin, 2. bitiş sırasını özel karakterle değiştirin, 3. özel karakteri kullanarak arama yapın, 4 özel karakteri geri değiştirin, 5. özel WORD'ü geri değiştirin. Örneğin, <hello> ve </hello> arasında açgözlü bir operatör istersiniz:
Jakub

3
İşte örnek: echo "Bul: <hello> fir ~ st <br> evet </hello> <hello> sec ~ ond </hello>" | sed -e "s, ~, VERYSPECIAL, g" -e "s, </hello>, ~, g" -e "s,. * Bul: <hello> ([^ ~] *). *, \ 1 , "-e" s, \ ~, </hello>, "-e" s, VERYSPECIAL, ~, "
Jakub

2
Katılıyorum. güzel bir çözüm. Söylemek için yorumu yeniden ifade ediyorum: Eğer kullanılmayan ~ güvenemezseniz, önce s / ~ / VERYspeciaL / g kullanarak mevcut olaylarını değiştirin, sonra yukarıdaki hile yapmak, sonra orijinal ~ s / VERYspeciaL / ~ / g kullanarak iade
ishahak

1
Ben bu tür şeyleri için nadir "değişkenleri" kullanarak, bu yüzden yerine benzeri eğilimindedir `, ben kullanırım <$$>beri ( $$sen tek tırnak yerine çift tırnak kullanmak zorunda olsa da, kabuğun içinde işlem kimliği için bir genişletme ve bu normal ifadenizin diğer bölümlerini kırabilir) veya unicode varsa benzer bir şey olabilir <∈∋>.
Adam Katz

Bir noktada size sadece kullanmadığınız neden kendinize sormalısınız perlveya pythonyerine başka bir dil veya. perlbunu tek bir satırda daha az kırılgan bir şekilde yapar ...
ArtOfWarfare

18

sed - Christoph Sieghart tarafından açgözlü olmayan eşleştirme

Sed'de açgözlü olmayan eşleşme elde etmenin hilesi, maçı sonlandıran karakter hariç tüm karakterlerle eşleşmektir. Biliyorum, beyinsiz, ama değerli dakikaları boşa harcadım ve kabuk komut dosyaları sonuçta hızlı ve kolay olmalı. Yani başka birinin buna ihtiyacı olabilirse:

Açgözlü eşleme

% echo "<b>foo</b>bar" | sed 's/<.*>//g'
bar

Açgözlü olmayan eşleme

% echo "<b>foo</b>bar" | sed 's/<[^>]*>//g'
foobar

17

Bu kesim kullanılarak yapılabilir:

echo "http://www.suepearson.co.uk/product/174/71/3816/" | cut -d'/' -f1-3

9

regex kullanmamak için başka bir yol alanlar / sınırlayıcı yöntemini kullanmaktır;

string="http://www.suepearson.co.uk/product/174/71/3816/"
echo $string | awk -F"/" '{print $1,$2,$3}' OFS="/"

5

sed kesinlikle bir yeri var ama bu onlardan biri değil!

Dee'nin belirttiği gibi: Sadece kullanın cut. Bu durumda çok daha basit ve çok daha güvenlidir. Bash sözdizimini kullanarak URL'den çeşitli bileşenleri çıkardığımız bir örnek:

url="http://www.suepearson.co.uk/product/174/71/3816/"

protocol=$(echo "$url" | cut -d':' -f1)
host=$(echo "$url" | cut -d'/' -f3)
urlhost=$(echo "$url" | cut -d'/' -f1-3)
urlpath=$(echo "$url" | cut -d'/' -f4-)

sana verir:

protocol = "http"
host = "www.suepearson.co.uk"
urlhost = "http://www.suepearson.co.uk"
urlpath = "product/174/71/3816/"

Gördüğünüz gibi bu çok daha esnek bir yaklaşım.

(hepsi Dee'ye verilir)



3

sed -E normal ifadeleri genişletilmiş (modern) normal ifadeler olarak yorumlar

Güncelleme: MacOS X'te -E, GNU sed'de -r.


4
Hayır, olmaz ... En azından GNU sed değil.
Michel de Ruiter

7
Daha geniş anlamda, -EBSD sedve dolayısıyla OS X'e özgüdür . Man sayfalarına bağlantılar. -ruzatıldı düzenli ifadeler getiriyor GNUsed @ stephancheg en düzeltme belirtildiği gibi. 'Nix dağıtımlarında bilinen değişkenlik komutunu kullanırken dikkatli olun. Bunu zor yoldan öğrendim.
fny

1
Sed kullanmak istiyorsanız doğru yanıt budur ve ilk soru için en uygun olanıdır.
Tice

8
GNU sed'in -rseçeneği Appendix A Extended regular expressions, bilgi dosyasına ve bazı hızlı testlere göre sadece kaçan kuralları değiştirir ; aslında ( GNU sed version 4.2.1en azından itibariyle) açgözlü olmayan bir niteleyici
eklemiyor

1
GNU sed -Ebir süredir belgelenmemiş bir seçenek olarak kabul edildi, ancak 4.2.2.177 sürümünde , belgeler bunu yansıtacak şekilde güncellendi, bu yüzden -Eher ikisi için de iyi.
Benjamin W.

3

Bunu saf (GNU) sed kullanarak çözmeyi umuyoruz. Bu, genel bir çözüm olmamasına rağmen, bazı durumlarda dizenin tüm gereksiz kısımlarını ortadan kaldırmak için "döngüler" kullanabilirsiniz:

sed -r -e ":loop" -e 's|(http://.+)/.*|\1|' -e "t loop"
  • -r: Genişletilmiş normal ifade kullan (+ ve çıkışsız parantez için)
  • ": loop": "loop" adlı yeni bir etiket tanımlayın
  • -e: sed'e komut ekle
  • "t loop": Başarılı bir değişiklik olursa "loop" etiketine atla

Buradaki tek sorun, son ayırıcı karakteri ('/') de keseceğidir, ancak gerçekten ihtiyacınız varsa, "döngü" bittikten sonra yine de geri koyabilirsiniz, sadece bu ek komutu bir öncekinin sonuna ekleyin Komut satırı:

-e "s,$,/,"

2

Özellikle sed (perl, cut vb. Yerine) kullanmaya çalıştığınızı belirttiğiniz için gruplandırmayı deneyin. Bu, potansiyel olarak tanınmayan açgözlü olmayan tanımlayıcıyı atlatır. İlk grup protokoldür (yani 'http: //', 'https: //', 'tcp: //' vb.). İkinci grup alan adıdır:

echo "http://www.suon.co.uk/product/1/7/3/" | sed "s | ^ \ (. * // \) \ ([^ /] * \). * $ | \ 1 \ 2 |"

Gruplamaya aşina değilseniz buradan başlayın .


1

Bunun eski bir giriş olduğunun farkındayım, ama birisi yararlı bulabilir. Tam alan adı toplam uzunluğu 253 karakteri geçemeyeceği için. * İle. \ {1, 255 \} yazın


1

Sed kullanarak çok karakterli dizelerin açgözlü olmayan eşleştirmesi bu şekilde yapılır. Her değiştirmek istediğiniz Diyelim foo...bariçin <foo...bar>böylece örneğin bu girişi:

$ cat file
ABC foo DEF bar GHI foo KLM bar NOP foo QRS bar TUV

bu çıktı olmalı:

ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV

Bunu yapmak için foo ve çubuğu ayrı ayrı karakterlere dönüştürür ve daha sonra bu karakterlerin aralarındaki olumsuzlamayı kullanırsınız:

$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/g; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV

Yukarıda:

  1. s/@/@A/g; s/{/@B/g; s/}/@C/gdönüştürülür {ve }girdide bulunmayan yer tutucu dizelere dönüştürülür , böylece bu grafikler dönüştürülebilir foovebar için.
  2. s/foo/{/g; s/bar/}/gdönüştürmektedir foove bariçin {ve }sırasıyla
  3. s/{[^{}]*}/<&>/gdönüştürme - istediğimiz op performans foo...bariçin<foo...bar>
  4. s/}/bar/g; s/{/foo/gdönüştürmektedir {ve }geri foove bar.
  5. s/@C/}/g; s/@B/{/g; s/@A/@/g yer tutucu dizelerini orijinal karakterlerine geri dönüştürüyor.

Yukarıdakilerin, ilk adımda bu tür dizeler ürettiği için girişte bulunmayan belirli bir dizeye dayanmadığını {[^{}]*}ve gerektiği kadar çok kez kullanabileceğiniz için hangi belirli regexp'in eşleşmesini istediğinizi önemsemediğini unutmayın. ifadesinde istediğiniz gerçek eşleşmeyi izole etmek ve / veya seds sayısal eşleme işleci ile, örneğin yalnızca 2. gerçekleşmeyi değiştirmek için:

$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/2; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC foo DEF bar GHI <foo KLM bar> NOP foo QRS bar TUV

1

Henüz bu cevabı görmedim, işte sen ile yapabilirsiniz nasıl viya vim:

vi -c '%s/\(http:\/\/.\{-}\/\).*/\1/ge | wq' file &>/dev/null

Bu, vi :%sikameyi global olarak çalıştırır (sondaki g), desen bulunamazsa ( e) bir hata vermekten kaçınır , daha sonra ortaya çıkan değişiklikleri diske kaydeder ve çıkar. &>/dev/nullÖnler can sıkıcı olabilir ekranda yanıp sönen kısaca GUI.

viBazen süper karmaşık regexes için kullanmayı seviyorum , çünkü (1) perl ölü ölüyor, (2) vim çok gelişmiş bir regex motoruna sahip ve (3) vigünlük kullanım düzenlememde regex'lere zaten aşinayım belgeler.


0
echo "/home/one/two/three/myfile.txt" | sed 's|\(.*\)/.*|\1|'

rahatsız etmeyin, başka bir forumda aldım :)


4
böylece açgözlü bir eşleşme elde edersiniz: /home/one/two/three/Eğer sizin /gibi bir tane daha eklerseniz /home/one/two/three/four/myfile.txtaçgözlülükle de eşleşirsiniz four:, /home/one/two/three/foursoru açgözlü değil
stefanB

0

sed 's|\(http:\/\/www\.[a-z.0-9]*\/\).*|\1| da çalışıyor


0

İşte iki aşamalı bir yaklaşım ve awk ile yapabileceğiniz bir şey:

A=http://www.suepearson.co.uk/product/174/71/3816/  
echo $A|awk '  
{  
  var=gensub(///,"||",3,$0) ;  
  sub(/\|\|.*/,"",var);  
  print var  
}'  

Çıktı: http://www.suepearson.co.uk

Umarım yardımcı olur!


0

Başka bir sed sürümü:

sed 's|/[:alnum:].*||' file.txt

/Ardından, alfasayısal bir karakterle (başka bir eğik çizgi ile değil) ve satır sonuna kadar kalan karakterlerle eşleşir . Daha sonra onu hiçbir şeyle değiştirmez (yani siler.)


1
Sanırım öyle olmalı "[[:alnum:]]", değil "[:alphanum:]".
oli_arborum
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.