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.
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
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"