it-swarm-eu.dev

Rozdíly mezi sedem na Mac OSX a jiným „standardním“ sedem?

Mám nějaké problémy s používáním odpovědi poskytnuté na tomto webu pro tato otázka o příkazu sed nahradí prázdný řádek dvěma dalšími řádky obsah , a to se objevilo, pokud byl příkaz sed v systému Mac OS (10.6.7 pro mě) je jiný. Nemyslím si, že je, ale přemýšlel jsem, jestli si ostatní na tomto webu myslí jinak.

67
Peter Grill

Chování obslužných programů Shell se u malých unixových variant liší. Existuje mnoho variant nix , s komplexníhistorie . Existují snahy o standardizaci , jako je POSIX standard a jeho superset Single UNIX specifikace . Většina systémů dnes implementuje POSIX: 2001, také známý jako Single UNIX Specification verze , s malými odchylkami a mnoha rozšířeními. Specifikace Single Unix není výukový program, ale verze 3 je čitelná, pokud již máte představu o tom, co příkaz dělá. Můžete se s ním seznámit a zjistit, zda je některá funkce standardem nebo rozšířením konkrétního systému.

Většina unixových uživatelů používá Linux a nevyužila žádnou jinou variantu. Linux je dodáván s nástroji GNU , které mají často mnoho rozšíření standardu. Takže tam najdete docela hodně kódu, který funguje na Linuxu, ale ne na jiných odvětvích, protože se spoléhá na tato rozšíření.

Pokud jde o sed, konzultujte specifikace sed Single Unix pro minimum, které má každý systém podporovat, manuální stránka ve vašem systém , co vaše implementace podporuje, a - GNU sed manual pro to, co většina lidí tam používá.

Jedno z nestandardních rozšíření v GNU sed podporuje více příkazů spuštěných společně). Například tento GNU sed program vytiskne všechny řádky obsahující a, ale nejdříve se změní b na c:

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

{ A } Jsou ve skutečnosti samostatné příkazy, takže pro plnou přenositelnost je musíte zadat buď na samostatných řádcích (v souboru) nebo v samostatných argumentech -e (Na příkazový řádek). Nedostatek oddělovače příkazů po { A použití ; Jako oddělovače příkazů jsou běžná rozšíření. Chybějící oddělovač příkazů před } Je méně obvyklé rozšíření. To je v souladu se standardem:

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

Toto je nestandardní, ale běžně přijímané:

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

Další nestandardní, ale běžné rozšíření je použití \n Pro označení nového řádku v nahrazujícím textu s (použití v regexpu je standardní). Přenosnou metodou je zahrnout zpětné lomítko-nový řádek do skriptu sed. Dalším běžným rozšířením je \+, \? A \| V regexpech, což znamená jednu nebo více, maximálně jednu a alternativní; přenosné základní regulární výrazy žádné z nich nemají. Například první příkaz je nepřenosný způsob nahrazení sousedících sekvencí mezer za novou řádek; druhý příkaz odpovídá standardům vyhovujícím.

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

OS X v současné době přichází s FreeBSD sed od roku 2005. Většina z níže uvedených rozdílů platí také pro jiné verze BSD sed.

Sedadla OS X používají -E pro ERE a GNU sed používá -r. -E je alias pro -r in GNU sed (přidáno v 4.2, dokumentováno až 4.3). Novější verze FreeBSD a NetBSD sed podporují oba -E a -r. OpenBSD sed podporuje pouze -E.

-i '' pracuje se sedadly OS X, ale ne GNU sed. -i pracuje s GNU sed, nejnovější verze NetBSD, OpenBSD sed, ale ne sed OS X. -i -e pracuje s oběma, ale v případě FreeBSD sed vytvoří zálohu původního souboru pomocí -e připojeno k názvu souboru (a do sed musíte předat více než jeden výraz).

GNU sed interpretuje únikové sekvence jako \t, \n, \001, \x01, \w, a \b. Sedadla OS X a POSIX sed interpretují pouze \n (ale ne v náhradní části s).

Interpretuje GNU sed \|, \+, a \? v BRE ale sed OS OS a POSIX sed ne. \(, \), \{, a \} jsou POSIX BRE.

GNU sed umožňuje vynechat ; nebo nový řádek před } ale OS X's sed ne.

i (insert), a (append) a c (change) musí následovat zpětné lomítko a nový řádek v sedech OS X a POSIX sed, ale nikoli v GNU sed. GNU sed přidá chybějící nový řádek za text vložený pomocí i, a nebo c ale OS X's sed ne. Například sed 1ia je GNU alternativa k sed $'1i\\\na\n'.

Například printf a|sed -n p přidá nový řádek do sedů OS X, ale ne do GNU sed.

Sedadla OS X nepodporují modifikátory I (nerozlišující malá a velká písmena) ani M (víceřádková). Novější verze FreeBSD sed podporují I.

Sedadla OS X nepodporují -s (--separate), -u (--unbuffered) nebo -z (--null-data).

Jedna možnost BSD, kterou nepodporuje GNU sed je -a, což způsobí, že se w připojí k souboru místo zkrácení souboru.

Příklady příkazů GNU sed, které nefungují se sedy 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
69
Lri

Nejlepší způsob, jak jsem zjistil, že mají stejný skript pro Linux i Mac, je:

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