O comportamento dos utilitários de shell difere de maneiras menores entre as variantes do unix. Existem muitas variantes unix , com uma história complexa . Existem esforços de padronização , como o padrão POSIX e seu superconjunto da especificação Single UNIX . Atualmente, a maioria dos sistemas implementa o POSIX: 2001, também conhecido como Single UNIX Specification versão 3 , com pequenos desvios e muitas extensões. A especificação Single Unix não é um tutorial, mas a versão 3 é legível se você já tiver uma idéia do que um comando está fazendo. Você pode consultá-lo para saber se algum recurso é padrão ou uma extensão de um sistema específico.
A maioria dos usuários unix usa Linux e não usou nenhuma outra variante. O Linux vem com utilitários GNU , que geralmente têm muitas extensões para o padrão. Então, você encontrará bastante código por aí que funciona no Linux, mas não em outros departamentos, porque depende dessas extensões.
Com relação ao sed, consulte a especificação sed Single Unix para obter o mínimo que todo sistema deve suportar, a página de manual do sistema para o que sua implementação suporta e o manual GNU sed para o que a maioria das pessoas usa.
Uma das extensões não padronizadas no GNU sed é oferecer suporte a vários comandos executados juntos. Por exemplo, este programa GNU sed imprime todas as linhas que contêm um a
, mas muda b
para o c
primeiro:
sed -ne '/a/ {s/b/c/g; p}'
{
e, }
na verdade, são comandos separados; portanto, para portabilidade total, é necessário especificá-los em linhas separadas (em um arquivo) ou em -e
argumentos separados (na linha de comando). A falta de um separador de comandos depois {
e o uso ;
como um separador de comandos são extensões comuns. A falta de um separador de comandos antes }
é uma extensão menos comum. Isso é compatível com o padrão:
sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'
Isso não é padrão, mas geralmente aceito:
sed -ne '/a/ { s/b/c/g; p; }'
Outra extensão comum, porém não-padrão, é o uso de \n
para significar uma nova linha em um s
texto de substituição (o uso em uma regexp é padrão). O método portátil é incluir a nova barra invertida no script sed. Outra extensão comum é \+
, \?
e \|
em regexps, para significar uma ou mais, no máximo uma e alternância; expressões regulares básicas portáteis não possuem nenhuma dessas. Por exemplo, o primeiro comando é uma maneira não portátil de substituir seqüências contíguas de espaço em branco por uma nova linha; o segundo comando é um equivalente compatível com os padrões.
sed -e 's/ \+/\n/'
sed -e 's/ */\
/'
sed
próprio GNU é compatível, pois faz as coisas permitidas (mas não exigidas, não especificadas) pelo padrão. Há casos em que não é compatível e onde a execuçãoPOSIXLY_CORRECT
no ambiente pode ajudar. Como coms/[\n]//g
isso, é necessário remover a folga e osn
caracteres, mas remover as novas linhas. Ou o comportamento doN
comando na última linha.sed -ne '/a/ { s/b/c/g; p; }'
é padrão desde a edição de 2016 da norma. Sempre foi portátil. Veja austingroupbugs.net/view.php?id=944&nbn=7Atualmente, o OS X vem com um sed do FreeBSD a partir de 2005. A maioria das diferenças abaixo também se aplica a outras versões do sed do BSD.
Os usos sed do OS X
-E
para usos sed ERE e GNU-r
.-E
é um alias para-r
no GNU sed (adicionado em 4.2, não documentado até 4.3). Versões mais recentes do FreeBSD e NetBSD sed suportam tanto-E
e-r
. O OpenBSD sed suporta apenas-E
.-i ''
funciona com o sed do OS X, mas não o GNU sed.-i
trabalha com GNU sed, versões recentes do NetBSD, OpenBSDsed
, mas não do OS X sed.-i -e
funciona com ambos, mas no caso do FreeBSDsed
faz um backup do arquivo original-e
anexado ao nome do arquivo (e você não precisa passar mais que uma expressãosed
).GNU interpreta sed sequências de escape como
\t
,\n
,\001
,\x01
,\w
, e\b
. O sed do OS X e o POSIX sed interpretam apenas\n
(mas não na parte de substituiçãos
).O GNU sed interpreta
\|
,\+
e\?
no BRE, mas o sed do OS X e o POSIX sed não.\(
,\)
,\{
, E\}
são POSIX BRE.O GNU sed permite omitir
;
ou uma nova linha antes,}
mas o sed do OS X não.i
(insert),a
(append) ec
(change) devem ser seguidos por uma barra invertida e uma nova linha no sed do OS X e no POSIX sed, mas não no GNU sed. Sed GNU acrescenta uma nova linha faltando após o texto inserido pori
,a
ouc
mas OS X da sed não. Por exemplo,sed 1ia
é uma alternativa ao GNUsed $'1i\\\na\n'
.Por exemplo,
printf a|sed -n p
adiciona uma nova linha no sed do OS X, mas não no GNU sed.O sed do OS X não suporta modificadores
I
( que não diferenciam maiúsculas de minúsculas) ouM
(multilinhas). Versões mais recentes do suporte ao FreeBSD sedI
.O sed do OS X não suporta
-s
(--separate
),-u
(--unbuffered
) ou-z
(--null-data
).Uma opção BSD que não é suportada pelo GNU sed é a
-a
quew
anexa a um arquivo em vez de truncar um arquivo.Exemplos de comandos GNU sed que não funcionam com o sed do OS X:
fonte
-i -e
não funciona no OSX. Interpeta-e
como o sufixo.-i
sempre exige um sufixo, mesmo que uma string vazia. então-i '' -e
deve funcionar.-i -e
funciona com ambos". na sua resposta sugere que existe uma solução de plataforma cruzada. Aparentemente não há.A melhor maneira de descobrir que o mesmo script funciona no Linux e no Mac é:
fonte
perl
onde isso-i
vem.perl -Tpi -e 's/foo/bar/' -- "$TARGET"