Preservar finais de linha

111

Executei o sed para fazer algumas substituições no windows e percebi que ele converte automaticamente as terminações de linha para Unix (\ n). Existe uma opção para dizer ao sed para usar terminações de linha do Windows (\ r \ n) ou ainda melhor para preservar as terminações de linha do arquivo?

Nota: Eu uso o sed da unxutils: http://unxutils.sourceforge.net/

Bogdan Calmac
fonte
2
As soluções abaixo não funcionam no macOS.
William Entriken
Eu cheguei até aqui e ainda não funcionouLC_ALL=C perl -i -e 'binmode $STDIN;undef $/;$_=<>;s|http://911coned.com|https://911coned.com|gm;print' education.html
William Entriken
Na verdade, o comando acima funciona e acabei de descobrir um bug no git diffprograma.
William Entriken
1
Você pode usar o sed (sem quaisquer opções especiais) + unix2dos
mems

Respostas:

143

Você pode usar a -bopção do sed para que ele trate o arquivo como binário. Isso resolverá o problema com o sed do cygwin no Windows.

Exemplo: sed -b 's/foo/bar/'

Se você deseja combinar o final da linha, lembre-se de combinar, capturar e copiar o retorno de carro opcional.

Exemplo: sed -b 's/foo\(\r\?\)$/bar\1/'

Na página de manual do sed :

-b --binary

Essa opção está disponível em todas as plataformas, mas só é eficaz quando o sistema operacional faz distinção entre arquivos de texto e arquivos binários. Quando tal distinção é feita - como é o caso do MS-DOS, Windows, Cygwin - os arquivos de texto são compostos de linhas separadas por um retorno de carro e um caractere de alimentação de linha, e o sed não vê o CR final. Quando esta opção é especificada, o sed abrirá os arquivos de entrada no modo binário, não solicitando este processamento especial e considerando que as linhas terminam em uma alimentação de linha.

Shlomo
fonte
5
Observe que isso não funciona sed -ino cygwin (para mim), mas você pode contornar isso. Obrigado pela atualização - as outras respostas foram a última palavra sobre este assunto por um tempo.
harpo
Observe que esta opção não está disponível com sed no Mac.
Senthil Kumaran
21
Funciona para mim mesmo com sed -i: é importante apenas como digitá-lo. Enquanto sed -bie sed -i -btrabalho, sed -ibfaz não trabalho: veja a página de manual para o porquê (usa o bcomo o sufixo para a cópia de segurança).
Olaf Mandel
2
Uso:sed -bi 's/foo/bar/'
Kunal B.
2
Não funciona para mim no Windows cygwin. Nas linhas que o sed fez a mudança, as terminações de linha são Unixy. O resto das linhas tem terminações de linha em janela. Portanto, meu arquivo recebeu uma mistura de linhas com diferentes finais de linha.
truthadjustr
10

Você pode tentar substituir o \nfor \r\nno final de seu script existente, assim:

sed 's/foo/bar/;s/$/\r/'

ou talvez

 sed -e 's/foo/bar/' -e 's/$/\r/'

Se nenhum dos dois acima funcionar, você terá que consultar a página de manual específica para sua versão do sedpara ver se tal opção existe. Note-se que as versões * nix de sedque não alteram os terminadores de linha sem ser dito para fazê-lo.

Outra alternativa é usar a cygwinversão sedque não deve ter esse comportamento indesejável.

SiegeX
fonte
15
A versão cygwin tem esse comportamento indesejável.
Harpo
2
Se o arquivo contém \ n ( 0x0A) e \ r \ n ( 0x0D 0x0A) - esta solução proposta (de sempre reinjetar o \ r) o quebra.
Vlad,
Isso funciona para mim usando MSYS2 / MinGW. Obrigado @SiegeX.
AntumDeluge
6

Alternativamente, (a versão cygwin de) perl -penão parece ter esse problema.

buscador
fonte
O sed no MacOS não tem a opção -b e tem problemas semelhantes aos descritos na pergunta original. A alternativa perl não tem esse problema, então obrigado por sua sugestão. sed -i -e 's/<img[^>]*\/>//g' *.xmlsubstitui terminações de linha por '\ n' perl -i -p -e 's/<img[^>]*\/>//g' *.xmlpreserva as terminações de linha originais
Guruniverse
2

O Gnuwin pode ser suprimido para bagunçar as novas linhas (win-> unix) se você especificar apenas a opção -b e o redirecionamento. Usar a opção -i (embutido) vai bagunçar tudo.

Por exemplo, sed.exe -b "s / \ xFF \ xFE //" c: \ temp \ in.csv> c: \ temp \ out.csv

Buckley
fonte
1
Veja uma versão com -imodo de trabalho em minha resposta .
Vadzim
2

Descobri que sed-4.4.exeem https://github.com/mbuilov/sed-windows é pura vitória, pois

  • usa terminações de linha do Windows CRLF no modo padrão
  • preserva finais de linha originais no -bmodo
  • funciona corretamente com o -imodo no local
  • também oferece -zmodo com \0delimitadores em vez do \nque pode ser útil às vezes também

Veja também a lista de opções do sed e a lista de todas as portas do Windows Sed .

Note-se que GnuWin32 sed 4.2.1 faz finais de linha corruptos em -bimodo e não tem -zmodo em tudo.

Vadzim
fonte