taşınabilir sed -e… db veya! b?


12

Gelen bu düzenleme Stéphane Chazelas POSIXifies (tekrar) benim sedbir ekleyerek biçimlendirme -eXPression mola ve başka -eXPression deyimi. Şimdi, neden yorumlarda ona sorabilirim, sanırım, ama bu cevapta zaten 18 numaralı revizyon var ve öncekilerin neredeyse hepsi benzer freebies sayesinde zaten oldu (silinen yorumları görebiliyorsanız, Yani) . Ayrıca, bunu neden daha genel olarak yararlı olabilecek bir şekilde ifade etmeyi anlamaya yeterince yakın olduğumu düşünüyorum . İşte umuyoruz ...

Genelde toplam sed -expressions'ımı bire bir tutmayı tercih ederim , ama aynı zamanda spesifikasyona olabildiğince yakın olarak uymak için daha fazla tercihim var , özellikle de fark bir <space>ve a'dan fazla değilse -e. Ama neden yapmam gerektiğini anlamıyorsam bunu yapamam . İşte şu anki durumumun kısa bir özeti:

  • ' -e 'mola portably bir vekâlet edebilir sedkomut \nbir de ewline mola sedkomut satırı deyimi ... Ben neden kuşkusuz bulanık değilim

  • bir sed {işlevdeki kapanış ayracı }öncesinde \n, burada belirtildiği gibi bir ewline sonu olmalıdır :

    • <right-brace>Bir önce yapılır <newline>ve önce veya sonra olabilir <blank>karakterler.
  • Bir \newline molası benzer ... her türlü kullanımından takip gereklidir a, b, c, i, r, t, w, veya :.

Ancak {fonksiyon }tanımının !operatör değil ile nasıl ilişkili olduğunu net bir şekilde anlamıyorum . Şartnamelerde olumsuzlama operatörü bulduğum tek söz:

  • Bir işlevden önce bir veya daha fazla !karakter olabilir, bu durumda adresler desen boşluğunu seçmezse işlev uygulanmalıdır.

Bu, !ima edilen {parantez kullanımı anlamına mı geliyor }? Hangi $!komutlar - aynı şekilde ' -e 'aralarla ayrılmalılar mı? Stéphane en son cevabımı POSIX hale getirdiğinde ele alınan bu muydu ?

Ben ya !olumsuzlama operatörü ya da bdüzenlemesinde ele aldığı ahır ifadesi olduğunu düşünüyorum - ya da muhtemelen her ikisi de aynı anda - ama bilmiyorum ve istemeliyim. Eğer durum bu ise , sadeceb çiftlik açıklamada, sonra ben inanıyorum bir dyerinde yapmak ve gereğini ortadan kaldıracak ' -e 'aradan, ama yerine bir üç kere hazarding önce belirli olurdu POSIXified cevabı. Yardım edebilir misin?

Sonuçta riske girdim , ama kesin olarak değil ...


Ile b;n;:b, ";n;:b"tarihsel ve POSIX seds denilen etikete dallıyorsunuz (ve GNU sed bu konuda değil).
Stéphane Chazelas

@ StéphaneChazelas - Rolü anladım :- o ay önce eve gittin. Ama ikinci sedkomutun neden benzer şekilde POSIXleştirildiğini tam olarak anlamıyorum .
mikeserv

1
Her durumda, POSIX spesifikasyonu benim için sedçok net değil. Geçmişte birkaç kez açıklama istedim, ancak sonuç olarak güncellendiğini sanmıyorum. İyi bir test, yadigâr araç testini denemektir (orijinalinden türetilen ve POSIX spesifikasyonunun büyük ölçüde dayandığı Solaris olanı).
Stéphane Chazelas

1
@syntaxerror - Durumun bu olduğuna inanmıyorum. şartnameyi s///okursanız, ubstitution'ların a ile zincirlemeyi kabul etmelerini şart koşarsınız ; . yeni satırla sınırlandırılması gereken komutlar etrafında bulanıklaşır ve -ebu durumda nasıl durabilir - en azından benim için öyle. ama ben sedonları oldukça değiştirilebilir olsa yorumlamıyor bir yanılmak için ive henüz .
mikeserv

1
@syntaxerror - Beğendim, ancak ;bir satırsonu öncesine ihtiyacınız olmadığını bilmelisiniz - satırsonu iyi. Dürüstçe, olabilir olmadan -etamamen ve tüm ve sadece gibi dosyası yazmak #!/bin/sedbir satır üzerinde her komutuyla - ya da bunun yerine sahip ayrılmış tür sınırlayıcı gerektirmez olanlar ;. Olanlar do yeni satırları gerektiren genellikle keyfi girdi almak olanlardır - :gibi onlara bakın etiket isimleri ve komutları bveya tveya kapama }fonksiyonları veya buraya curlies rEAD ve wdosya adı args almak ayin. Hepsi portatif olarak takip edilmelidir \n.
mikeserv

Yanıtlar:


4

Bu yüzden bu sorunun bir cevabı vardı ve bir süre önce hemen hemen her durumda bunu nasıl doğru bir şekilde yapılacağımı sezgisel olarak çözsem de , sadece son zamanlarda bu anlayışı standarttaki metinle oldukça somutlaştırmayı başardım. . Aslında orada oldukça basit bir şekilde ifade edildi - aptalca birçok kez göz ardı ettim, sanırım.

Metnin ilgili bölümlerinin tümü başlığın altında bulunur ...

  • Komutları şurada düzenlemesed :

    • Argüman metni bir veya daha fazla satırdan oluşur. \nMetindeki her gömülü ewline'dan önce bir \ters eğik çizgi gelmelidir . Metindeki diğer ters eğik çizgiler kaldırılacak ve aşağıdaki karakter tam anlamıyla ele alınacaktır.

    • rVe wkomut fiiller ve wbayrak skomutu, isteğe bağlı bir almak RDOSYA (veya wfile bir veya daha fazla harf veya bayrak fiil komut ayrılmış) bir parametre olan <blank>s; uygulamalar bir uzantı olarak sıfır ayrımına izin verebilir.

    • Komut dışındaki fiiller {, a, b, c, i, r, t, w, :, ve #bir tarafından takip edilebilir ;noktalı virgül, isteğe bağlı <blank>sve başka bir komut fiil. Ancak, skomut fiili wbayrakla birlikte kullanıldığında , başka bir komutla bu şekilde izlenmesi tanımsız sonuçlar üretir.

...içinde...

  • Seçenekler: Çoklu -eve -fseçenekler belirtilebilir. Tüm komutlar, kökenlerine bakılmaksızın, komut dosyasına belirtilen sırada eklenmelidir.

    • -e senaryo - tarafından belirtilen düzenleme komutları ekleyin komut sonuna seçeneği-argüman komut düzenleme komutları. Komut seçeneği-argüman olarak aynı özelliklere sahip olacaktır senaryo açıklanan işlenen, işlenenler bölümünde.

    • -f script_file - script_file dosyasındaki düzenleme komutlarını komut dosyasının sonuna ekleyin .

Ve son olarak ...

  • Operandlar:

    • script - Komutları düzenleme komut dosyası olarak kullanılacak dize . Uygulama, son karakterin bir ewline olması gerekmediği sürece, metin dosyasının kısıtlamalarını ihlal eden bir komut dosyası\n sunamaz.

Bu nedenle, tamamen aldığınızda, isteğe bağlı olarak, önceden tanımlanmış bir sınırlayıcı olmadan isteğe bağlı bir parametre tarafından izlenen herhangi bir komutun ( s d sub d repl d flagörneğin aksine )\n kaçışsız bir ewline'da sınırlanması gerekir .

Bunun önceden tanımlanmış bir sınırlayıcı ; olduğu iddia edilebilir, ancak bu durumda ;herhangi bir [aic]komut için for'un kullanılması, özellikle bu üç komut için ayrı bir ayrıştırıcının dahil edilmesini gerektirecektir - ayrı olarak, [:brw]örneğin, kullanılan ayrıştırıcıdan . Yoksa uygulama gerektirir olurdu ; da ters eğik çizgi içindeki çıkışı olması metin parametresi ve sadece daha oradan karmaşık büyür.

Eğer ben bir yazdığımız sedI uyumlu ve verimli olmamızı arzu hangi, o zaman böyle bir ayrı ayrıştırıcı yazmak olmaz, ben bekliyoruz - belki hariç [aic]gerektiği gen bir sözdizimi hatası hemen ardından değilse \newline. Ancak bu basit bir belirteç sorunudur - son sınırlayıcı durum genellikle daha sorunludur. Ben sadece şöyle yazardım:

sed -e w\ file\\ -e one -e '...;and more commands'

...ve...

sed -e a\\ -e appended\\ -e text -e '...;and more commands'

... birincisi benzer bir şekilde davranır, çünkü ilki şu adlı bir dosya oluşturur ve ona yazar:

file
one

... ve ikincisi çıktıdaki mevcut satıra bir metin bloğu ekler ...

appended
text

... çünkü her ikisi de parametre için aynı ayrıştırma kodunu paylaşacaktı.

Ve ilgili { ... }ve $!sorunu - iyi, ben yolu kapalı oldu. Bir adres öncesinde tek komuttur değil bir işlev daha ziyade bu sadece bir komut ele olduğunu. Hemen hemen tüm komutlar - { işlev tanımı } da dahil olmak üzere , yorum ve etiket tanımı hariç olmak üzere kabul /one/veya /one/,/two/adresler belirtilir . Ve bir adres bir satır numarası veya normal bir ifade olabilir ve ile reddedilebilir . Yani hepsi ...#:!

$!d
/address/s/ub/stitution/
5!y/d/c/

... ;standartlara göre bir ve daha fazla komut izleyebilir , ancak tek bir adres için daha fazla komut gerekiyorsa ve bu adres her komutun yürütülmesinden sonra yeniden değerlendirilmemelidir, aşağıdaki gibi bir {işlev }kullanılmalıdır:

/address/{ s//replace addressed pattern/
           s/do other conditional/substitutions/
           s/in the same context/without/
           s/reevaluating/address/
}

... burada {aynı satırda bir kapanışla izlenemez ve satırın başlangıcı dışında }bir kapanış }gerçekleşemez. Ancak içerilen bir komutun başka şekilde bir \newline izlemesi gerekmiyorsa, işlev içinde de olması gerekmez. Böylece yukarıdaki tüm s///ikame - ve hatta kapanış }ayracı, taşınabilir olarak ;noktalı virgül ve diğer komutlar tarafından takip edilebilir .

Ben \newline sınırlayıcıları hakkında konuşmaya devam ediyorum ama soru bunun yerine xpression -eifadeleri hakkında, biliyorum. Ancak ikisi gerçekten bir ve aynıdır ve anahtar ilişki, bir komut dosyasının ya tam bir komut satırı argümanı ya da ikisinden biriyle bir dosya -[ef]olabileceği ve her ikisinin de metin dosyaları ( \newline) ama hiçbiri ihtiyaç aslında sona bir de \newline. Bununla ben reasonbly olabilir (I umut) bir o anlaması \0NULayrılmış argümanı bir bitiş ima \nbütün çağırma argümanlar olsun ewline ve ) en az bir \0NULNeyse sınırlayıcı, ardından ya cezası çalışmalıdır.

Aslında, pratikte, her durumda, ancak standardın \ters eğik çizgiden kaçan bir yeni satır belirttiği bir durum gerekli olmalıdır, taşınabilir bulduk ...

sed -e ... -e '...\' -e '...'

... aynı şekilde çalışmak. Ve her durumda - yine, pratikte - \nkaçmayan bir ewline'ın gerekli olduğu yerlerde ...

sed -e '...' -e '...'

... benim için de çalıştı. Yukarıda bahsettiğim tek istisna ...

sed -e 's/.../...\' -e '.../'

... hiçbir testte hiçbir uygulama için çalışmaz. Metin dosya gereksinimi ve bir sınırlayıcı ile birlikte s/// gelen gerçeğe geri oldukça eminim ve bu nedenle tek bir deyim \0NULsınırlandırılmış argümanlar yayılması için bir neden yoktur .

Sonuç olarak, burada birkaç tür sedkomut yazmanın taşınabilir yollarının kısa bir özeti :

Herhangi biri için [aic]:

...commands;[aic]\
text embedded newline\
delimiting newline
...more;commands...

...veya...

sed -e '...commands;[aic]\' -e 'text embedded newline\' -e 'delimiting newline' -e '.;.;.'

Herhangi biri için [:rwtb]burada parametresi olan isteğe (tüm ama için :) , ancak sınırlandırma \newline olduğu değildir . Not Birden fazla hat denemek için bir sebep yoktu o etiket ile kullanılabilir gibi parametreleri [:tb], ama bu writing / rçoklu hatlara eading [rw] dosya parametreleri genellikle tarafından sorgulanmadan kabul görür sedı gömülü sürece test ettik s \newline \ters eğik çizgi kullanmadan kaçtı . Yine de standart, etiket ve [rw] dosya parametrelerinin metne aynı şekilde ayrıştırılması gerektiğini doğrudan belirtmezparametrelerini \nbelirtir ve ilk ikisi ile ilgili sınır çizgileri dışında ewline'lardan söz etmez .

...commands;[:trwb] parameter
...more;commands...

...veya...

sed -e '[:trwb] parameter' -e '...'

... <space>yukarıdakiler isteğe bağlıdır [:tb].

Ve son olarak...

...;address[!]{ ...function;commands...
};...more;commands....

...veya...

sed -e '...;address[!]{ ...function;commands...' -e '};...more;commands...'

... yukarıda sözü edilen komutların herhangi bir yerde (hariç :) ayrıca en az bir kabul adresi olan ve bir ya da olabilir /düzenli ifadesi /ya da bir satır sayısı ile etkisiz olabilir !, birden çok komut tek bir değerlendirme için gerekli olduğu takdirde, ancak adresi sonra {fonksiyon bağlamı }sınırlayıcı ayraçlar kullanılmalıdır. Bir işlev birden fazla \newline sınırlandırılmış komut bile içerebilir , ancak her biri diğer şekillerde olduğu gibi parantez içinde sınırlandırılmalıdır.

Taşınabilir sedkomut dosyaları bu şekilde yazılır .


2
Neden kendi cevabını kabul etmiyorsun?
Philippos
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.