Mac OSX'teki sed ile diğer "standart" sed arasındaki farklar?


Yanıtlar:


43

Kabuk yardımcı programlarının davranışı, unix değişkenleri arasında küçük şekillerde farklılık gösterir. Karmaşık bir geçmişi olan birçok unix çeşidi vardır . Orada standartlaştırma çalışmaları gibi POSIX standardı ve onun üst dizisi Tek UNIX şartname . Günümüzde çoğu sistem , küçük sapmalara ve birçok uzantıya sahip olan Tek UNIX Spesifikasyonu sürüm 3 olarak da bilinen POSIX: 2001'i uygular . Tekli Unix özelliği bir öğretici değildir, ancak bir komutun ne yaptığı hakkında bir fikriniz varsa, sürüm 3 okunabilir. Bazı özelliklerin standart olup olmadığını veya belirli bir sistemin bir uzantısı olup olmadığını öğrenmek için başvurabilirsiniz.

Unix kullanıcılarının çoğu Linux kullanıyor ve başka bir değişken kullanmamışlar. Linux , çoğu zaman standarda birçok eklenti içeren GNU yardımcı programları ile birlikte gelir . Yani orada Linux üzerinde çalışan fakat diğer birliklerde çalışmayan bir sürü kod bulacaksınız, çünkü bu uzantılara dayanmaktadır.

Sed ile ilgili olarak, her sistemin desteklemesi gereken minimum , sed uygulamasının desteklediği şeyler için sisteminizdeki man sayfasına ve orada bulunan kişilerin çoğunun kullandığı GNU sed kılavuzuna yönelik sed Single Unix teknik özelliklerine bakın .

GNU sed'deki standart olmayan uzantılardan biri, birlikte çalışan çoklu komutları desteklemektir. Örneğin, bu GNU programı baskılar her bir içeren satırları sed a, fakat herhangi bir değişiklik bhalinde cbirinci:

sed -ne '/a/ {s/b/c/g; p}'

{ve }aslında ayrı komutlardır, bu nedenle tam taşınabilirlik için bunları ayrı satırlarda (bir dosyada) veya ayrı -ebağımsız değişkenlerde (komut satırında) belirtmeniz gerekir . Sonradan bir komut ayırıcının olmaması {ve ;komut ayırıcı olarak kullanılması yaygın uzantılardır. Daha önce bir komut ayırıcısının olmaması }daha az yaygın bir uzatmadır. Bu standart uyumludur:

sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'

Bu standart değildir ancak yaygın olarak kabul edilir:

sed -ne '/a/ { s/b/c/g; p; }'

Standart olmayan ancak ortak bir başka uzantı, değiştirilen metinde \nyeni bir satırın skullanılmasıdır (regexp'te kullanım standarttır). Taşınabilir yöntem sed betiğine ters eğik çizgi olarak eklenmektir. Bir başka ortak uzantısı \+, \?ve \|regexp'lere en fazla bir ve nöbetleşe olarak bir veya daha fazla, anlamında kullanılır; taşınabilir temel düzenli ifadelerde bunlardan hiçbiri yoktur. Örneğin, ilk komut, boşlukların bitişik dizilerini bir yenisiyle değiştirmenin taşınabilir olmayan bir yoludur; ikinci komut standartlara uygun bir eşdeğerdir.

sed -e 's/ \+/\n/'
sed -e 's/  */\
/'

GNU uzantılarıyla ilgili tüm bu durumlarda, standart olmayan kullanım olduğunu unutmayın. GNU sed, standart tarafından izin verilen (ancak gerekli olmayan, belirtilmeyen) şeyleri yerine getirdiği için uyumludur. Uyumlu olmadığı ve POSIXLY_CORRECTortamda çalıştırmanın yardımcı olabileceği durumlar vardır. Bunun gibi s/[\n]//gboşlukları ve nkarakterleri kaldırmalı fakat bunun yerine yeni satırları kaldırmalı. Veya Nson satırdaki komutun davranışı .
Stéphane Chazelas

sed -ne '/a/ { s/b/c/g; p; }'standardın 2016 sayısından bu yana standarttır. Her zaman taşınabilirdi. Bkz austingroupbugs.net/view.php?id=944&nbn=7
Stéphane Chazelas

60

OS X şu anda 2005'ten itibaren FreeBSD sed ile birlikte geliyor. Aşağıdaki farklılıkların çoğu diğer BSD sed versiyonları için de geçerli.

OS X'in sed -EERE ve GNU sed kullanır -r. GNU sed -Eiçin bir takma -raddır (4.2'ye eklenmiştir, 4.3'e kadar belgelenmemiş). FreeBSD ve NetBSD'nin SED yeni versiyonları her ikisini de destekler -Eve -r. OpenBSD sed sadece desteklemektedir -E.

-i ''OS X’lerin sed ile çalışır ancak GNU sed ile değil. -iGNU sed, NetBSD'nin son sürümleri, OpenBSD ile çalışır sed, ancak OS X'in sed'i değildir. -i -eher ikisi ile çalışır ancak FreeBSD durumunda , dosya adına eklenmiş sedorijinal dosyanın yedeğini alır -e(ve birden fazla ifadeye geçmeniz gerekmez sed).

GNU sed, yorumlanması gibi dizileri kaçış \t, \n, \001, \x01, \w, ve \b. OS X'in sed ve POSIX sed yalnızca yorumluyor \n(ancak bunun yerine kullanılmıyor s).

GNU, yorumlanması sed \|, \+ve \?BRE ama OS X'in sed ve POSIX sed yapamaz. \(, \), \{Ve \}POSIX BRE vardır.

GNU sed, daha ;önce ihmal edilmesine veya yeni bir satır }olmasına izin verir, ancak OS X'in sed'i değildir.

i(insert), a(append) ve c(change) ardından bir ters eğik çizgi ve OS X'in sed ve POSIX sed'sindeki yeni bir satır ve GNU sed'de bulunmaması gerekir. GNU sed tarafından eklenen metinden sonra bir eksik yeni satır ekler i, aya csed ancak OS X en etmez. Örneğin sed 1iabir GNU alternatifidir sed $'1i\\\na\n'.

Örneğin printf a|sed -n p, OS X'in sed'ine yeni bir satır ekler, ancak GNU sed'de değil.

OS X'in sed'i I(büyük / küçük harfe duyarsız) veya M(çok satırlı) değiştiricileri desteklemez. FreeBSD sed'nin daha yeni sürümleri I.

OS X'in sed -s( --separate), -u( --unbuffered) veya -z( --null-data) desteklemiyor.

GNU sed tarafından desteklenmeyen bir BSD seçeneği, dosyayı kesmek yerine bir dosyaya eklemeyi -ayapar w.

OS X'in sed ile çalışmayan GNU sed komutlarına örnekler:

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a shell command
sed -n l0 # 0 disables wrapping

4
-i -eOSX üzerinde çalışmıyor. Bu interpets -eson eki olarak.
Chris Martin

3
@ChrisMartin evet, OS X sürümünde -iboş bir dize olsa bile daima bir sonek gerekir. bu yüzden -i '' -eçalışması gerekir.
waldyrious

@ waldyrious Sadece OSX'de çalışır.
Chris Martin

evet, bu sürümün bir
tuhaflık

3
Cümle " -i -eher ikisi ile de çalışır." Cevabınızda bir çapraz platform çözümü olduğunu göstermektedir. Görünüşe göre yok.
Leondepeon

5

Hem Linux hem de Mac'te aynı senaryo çalışmasına sahip olduğumun en iyi yolu:

sed -i.bak -e 's/foo/bar/' -- "${TARGET}" &&
  rm -- "${TARGET}.bak"

Ya da perlnereden -igeldiğini kullanın . perl -Tpi -e 's/foo/bar/' -- "$TARGET"
Stéphane Chazelas
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.