Existe algum problema com o caracter sed e nova linha?
Eu tenho um arquivo test.txt com o seguinte conteúdo
aaaaa
bbbbb
ccccc
ddddd
O seguinte não funciona:
sed -r -i 's/\n/,/g' test.txt
Eu sei que posso usar tr
isso, mas minha pergunta é por que não parece possível com o sed.
Se esse é um efeito colateral do processamento do arquivo linha por linha, eu estaria interessado em saber por que isso acontece. Eu acho que grep
remove novas linhas. Sed faz o mesmo?
tr
adicionaria um final,
e produziria uma linha não terminada. Melhor é usarpaste
:paste -sd , test.txt
Respostas:
Com GNU
sed
e fornecidoPOSIXLY_CORRECT
não está no ambiente (para entrada de linha única):Em https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n :
:a
N
$!ba
($!
significa não fazê-lo na última linha (pois deve haver uma nova linha final)).fonte
ba: Event not found
sed
comando acima com essas opções exatas? Em qualtest.txt
arquivo? Com qual versão dosed
(tentarsed --version
)?!
. Curiosamente, isso ainda não funcionou para mim e acabei tendo que escapar duas vezes do!
meu.csh
script. Então, eu realmente não tenho um problema no momento, mas você sabe por que isso pode ser? O que funcionou para mim foised :a;N;$\\!ba;s/\n/ /g'
Isso funciona com o GNU
sed
:-z
está incluído desde 4.2.2NB
-z
altera o delimitador para caracteres nulos (\0
). Se sua entrada não contiver caracteres nulos, toda a entrada será tratada como uma única linha. Isso pode vir com suas limitações .Para evitar a substituição da nova linha da última linha, você pode alterá-la novamente:
(Que é a
sed
sintaxe do GNU novamente, mas não importa, porque tudo é apenas GNU)fonte
No site da Oracle:
Basicamente, isso significa que, porque sed está lendo linha por linha, o caractere de nova linha não é correspondido.
A solução em https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n é:
ou, em uma versão portátil (sem
;
concatenar após os rótulos das marcas de salto)Uma explicação sobre como isso funciona é fornecida nessa página.
fonte
sed
, se POSIXLY_CORRECT estiver no ambiente e a entrada tiver apenas uma linha, não haverá saída.sed
sempre remove o\n
ewline à direita antes de preencher o espaço do padrão e, em seguida, acrescenta um antes de escrever os resultados do script. Uma linha de\n
ew pode ser obtida no espaço do padrão por vários meios - mas nunca se não for o resultado de uma edição. Isso é importante - as\n
linhas nosed
espaço do padrão sempre refletem uma alteração e nunca ocorrem no fluxo de entrada.\n
As linhas de linha são o único delimitadorsed
em que o contador pode contar com informações desconhecidas.Se você deseja substituir todas as
\n
linhas eletrônicas por vírgulas e seu arquivo não for muito grande, faça o seguinte:Isso anexa todas as linhas de entrada ao
h
espaço antigo - exceto o primeiro, que substitui oh
espaço antigo - após um\n
caractere de linha de linha. Eled
exclui todas as linhas, não as$!
últimas da saída. Na última linhaH
, os espaços antigos e padrão sãox
alterados e todos os\n
caracteres da linha sãoy///
traduzidos para vírgulas.Para arquivos grandes, esse tipo de coisa provavelmente causará problemas -
sed
o buffer dos limites de linha, que pode ser facilmente transbordado com ações desse tipo.fonte
Como alternativa, você pode usar uma sintaxe um pouco mais simples:
... apenas mudando a ordem da sequência.
fonte
s
comando para cada linha de entrada em um espaço padrão cada vez maior.Há uma mágica sed muito agradável aqui. E alguns bons pontos levantados sobre o excesso de espaço do padrão. Adoro usar o sed, mesmo quando não é o caminho mais simples, porque é muito compacto e poderoso. No entanto, ele tem limitações e, para grandes quantidades de dados, o espaço do padrão teria que ser mahoosivo.
O GNU diz o seguinte:
Não tenho muito a acrescentar, mas gostaria de apontá-lo para o meu guia para sed . É excelente. http://www.grymoire.com/Unix/Sed.html
e aqui está a minha solução:
bem, funciona
fonte
Digamos que você queira substituir as novas linhas por
\n
. Eu queria fazer isso, então aqui está o que eu fiz:Aqui está o que ele faz: para todas as linhas, exceto a última , acrescente
\n
. Em seguida, exclua as novas linhas comtr
.fonte
-r
está disponível apenas no GNUsed
, não no BSD.