Różnice między sedem w Mac OSX a innym „standardowym” sedem?


Odpowiedzi:


43

Zachowanie narzędzi powłoki różni się nieznacznie między wariantami unixa. Istnieje wiele wariantów uniksowych o złożonej historii . Podejmowanedziałania normalizacyjne, takie jak standard POSIX i jego nadzbiór nad specyfikacją Single UNIX . Obecnie większość systemów implementuje POSIX: 2001, znany również jako specyfikacja Single UNIX wersja 3 , z niewielkimi odchyleniami i wieloma rozszerzeniami. Specyfikacja Single Unix nie jest samouczkiem, ale wersja 3 jest czytelna, jeśli już wiesz, co robi polecenie. Możesz skonsultować się z nim, aby dowiedzieć się, czy jakaś funkcja jest standardem czy rozszerzeniem określonego systemu.

Większość użytkowników Uniksa używa Linuksa i nie użyła żadnego innego wariantu. Linux jest dostarczany z narzędziami GNU , które często mają wiele rozszerzeń standardu. Znajdziesz więc sporo kodu, który działa na Linuksie, ale nie na innych unikach, ponieważ opiera się na tych rozszerzeniach.

Jeśli chodzi o sed, zapoznaj się ze specyfikacją sed Single Unix, aby poznać minimum, które powinien obsługiwać każdy system, stronę podręcznika systemowego, która obsługuje implementację, oraz instrukcję GNU sed, z której korzysta większość osób.

Jedno z niestandardowych rozszerzeń GNU sed obsługuje wiele poleceń uruchamianych razem. Na przykład ten program GNU sed wypisuje wszystkie linie zawierające a, ale zmienia się bw cpierwszy:

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

{i }tak naprawdę są osobnymi poleceniami, więc dla pełnej przenośności musisz je określić albo w osobnych wierszach (w pliku), albo w osobnych -eargumentach (w wierszu poleceń). Brak separatora poleceń po {i użycie ;jako separatora poleceń są powszechnymi rozszerzeniami. Brak separatora poleceń wcześniej }jest rzadszym rozszerzeniem. Jest to zgodne ze standardami:

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

Jest to niestandardowe, ale powszechnie akceptowane:

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

Innym niestandardowym, ale powszechnym rozszerzeniem jest użycie \nznaku nowej linii w stekście zastępczym (użycie wyrażenia regularnego jest standardowe). Przenośną metodą jest uwzględnienie odwrotnego ukośnika w skrypcie sed. Innym powszechnym rozszerzeniem jest \+, \?a \|wyrażenia regularne oznacza jedno lub więcej, co najwyżej jedno i na przemian; w przenośnych podstawowych wyrażeniach regularnych nie ma żadnego z nich. Na przykład pierwsze polecenie jest nieprzenośnym sposobem zastępowania ciągłych sekwencji białych znaków nową linią; drugie polecenie jest odpowiednikiem zgodnym ze standardami.

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

Zauważ, że we wszystkich tych przypadkach dotyczących rozszerzeń GNU jest to użycie niestandardowe. sedSam GNU jest zgodny, ponieważ pozwala na rzeczy dozwolone (ale nie wymagane, nieokreślone) przez standard. Są przypadki, w których jest niezgodny i gdzie POSIXLY_CORRECTmoże pomóc uruchomienie go w środowisku. Podobnie jak w przypadku s/[\n]//gtego, należy usunąć luz i nznaki, ale zamiast tego usunąć nowe linie. Lub zachowanie Npolecenia w ostatnim wierszu.
Stéphane Chazelas,

sed -ne '/a/ { s/b/c/g; p; }'jest standardem od wydania normy 2016. Zawsze był przenośny. Zobacz austingroupbugs.net/view.php?id=944&nbn=7
Stéphane Chazelas

60

OS X jest obecnie wyposażony w wersję FreeBSD sed z 2005 roku. Większość poniższych różnic dotyczy także innych wersji BSD sed.

Zastosowania sed OS X dla zastosowań -EERE i GNU sed -r. -Eto alias dla -rGNU sed (dodany w 4.2, nieudokumentowany do 4.3). Nowsze wersje FreeBSD i NetBSD sed obsługują zarówno -Ei -r. OpenBSD sed obsługuje tylko -E.

-i ''działa z sed OS X, ale nie z GNU sed. -iwspółpracuje z GNU sed, najnowszymi wersjami NetBSD, OpenBSD sed, ale nie sed OS X. -i -ewspółpracuje z obydwoma, ale w przypadku FreeBSD sedwykonuje kopię zapasową oryginalnego pliku z -edopisaniem do nazwy pliku (i musisz przekazać nie więcej niż jedno wyrażenie sed).

GNU sed interpretuje sekwencje, takie jak \t, \n, \001, \x01, \w, i \b. Sed OS X i POSIX sed interpretują tylko \n(ale nie w części zamiennej s).

GNU sed interpretuje \|, \+oraz \?w BRE ale sed i POSIX sed OS X za nie. \(, \), \{, I \}są POSIX BRE.

GNU sed pozwala na pomijanie ;lub nową linię wcześniej, }ale sed OS X nie.

i(wstaw), a(dołącz) i c(zmień) muszą być poprzedzone odwrotnym ukośnikiem i nową linią w sed OS X i POSIX sed, ale nie w GNU sed. Sed GNU dodaje brakujący przełamane po tekście włożonej przez i, alub cale OS X sed nie. Na przykład sed 1iajest GNU alternatywą dla sed $'1i\\\na\n'.

Na przykład printf a|sed -n pdodaje nową linię w sed OS X, ale nie w GNU sed.

Sed OS X nie obsługuje modyfikatorów I(bez uwzględniania wielkości liter) ani M(wielu linii). Nowsze wersje wsparcia dla FreeBSD sed I.

Sed OS X nie obsługuje -s( --separate), -u( --unbuffered) ani -z( --null-data).

Jedną z opcji BSD, która nie jest obsługiwana przez GNU sed -a, jest wdodanie pliku do pliku zamiast obcięcia go.

Przykłady poleceń GNU sed, które nie działają z sed OS X:

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 -enie działa na OSX. Interetuje -ejako przyrostek.
Chris Martin

3
@ChrisMartin tak, w wersji OS X -izawsze wymaga sufiksu, nawet jeśli pusty ciąg. tak -i '' -epowinno działać.
waldyrious

@waldyrious Działa tylko na OSX.
Chris Martin

tak, to dziwactwo tej wersji :)
waldyrious

3
Zdanie „ -i -edziała z oboma”. w twojej odpowiedzi sugeruje, że istnieje rozwiązanie wieloplatformowe. Najwyraźniej nie ma.
leondepeon

5

Najlepszym sposobem, w jaki znalazłem taką samą pracę skryptów w systemach Linux i Mac jest:

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

Lub użyj perlskąd -ipochodzi. perl -Tpi -e 's/foo/bar/' -- "$TARGET"
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.