Novas linhas no sed no Mac OS X

35

Acho que \n não funciona em sed no Mac OS X. Especificamente, digamos que quero dividir as palavras separadas por um único espaço em linhas:

# input
foo bar

eu uso,

echo "foo bar" | sed 's/ /\n/'

Mas o resultado é estúpido, o \n não é ignorado!

foonbar

Depois de consultar o Google, encontrei uma solução alternativa :

echo 'foo bar' | sed -e 's/ /\'$'\n/g'

Depois de ler o artigo, ainda não consigo entender o que \'$'\n/g' significa. Alguém pode explicar para mim, ou se existe alguma outra maneira de fazer isso? Obrigado!

    
por Ivan Z. G. Xiao 06.07.2011 / 18:01

5 respostas

23

Você pode brew install gnu-sed e substituir chamadas para sed com gsed .

Se você não quiser preceder o "g" a sed , poderá brew install gnu-sed --with-default-names e apenas chamar sed .

(edite: atualize a bandeira brew, dê gorjeta para Clément.)

    
por 14.04.2013 / 03:33
18

Isso também funcionaria:

echo 'foo bar' | sed 's/ /\
/g'

echo 'foo bar' | sed $'s/ /\\n/g'

lf=$'\n'; echo 'foo bar' | sed "s/ /\$lf/g"

O sed do OS X não interpreta \n no padrão de substituição, mas você pode usar um avanço de linha literal precedido por um caractere de continuação de linha. O shell substitui $'\n' por um avanço de linha literal antes do comando sed ser executado.

    
por 07.07.2011 / 07:58
10

A solução alternativa que você encontrou passou uma única string de argumento para sed -e .

Esse argumento acaba sendo uma string no familiar formato sed s/ / /g .

Essa string é criada em duas partes, uma após a outra.

A primeira parte é citada em '...' form.

A segunda parte é citada em $'...' form.

A parte 's/ /\' obtem as aspas simples removidas, mas de outra forma passa para sed exatamente como aparece na linha de comando. Ou seja, a barra invertida não é comida por bash, é passada para sed.

A parte $'\n/g' obtém o sinal de dólar e as aspas simples removidas, e o \n é convertido em um caractere de nova linha.

Todos juntos, o argumento se torna

s / / \ nova linha / g

[Isso foi divertido. Demorou um pouco para desembrulhar isso. +1 para uma pergunta interessante.]

    
por 07.07.2011 / 05:57
6

A expressão $'...' é um bash -ism que produz ... com as sequências de escape padrão expandidas. Th \' antes significa apenas uma barra invertida seguida do final da seção entre aspas, a string resultante é s/ /\ . (Sim, você pode alternar entre aspas no meio de uma string; não termina a string.)

Padrão POSIX sed aceita somente \n como parte de um padrão de pesquisa. O OS X usa o FreeBSD sed , que é estritamente compatível com POSIX; O GNU, como de costume, adiciona coisas extras e então todos os usuários do Linux acham que isso é algum tipo de "padrão" (talvez eu ficaria mais impressionado se algum deles tivesse um processo de padrões).

    
por 06.07.2011 / 18:15
0

É muito fácil ver visualmente o que está acontecendo. Simplesmente ecoa a corda!

echo 's/$/\'$'\n/g'

resulta em

s/$/\
/g

que é equivalente a s/$/\ nova linha /g

Se você não tiver o \ extra antes do newline , o shell interpretará o newline como o final do comando prematuramente.

    
por 27.10.2017 / 03:36