Conservar los finales de línea

111

Ejecuté sed para hacer una sustitución en Windows y noté que convierte automáticamente los finales de línea a Unix (\ n). ¿Existe una opción para decirle a sed que use los finales de línea de Windows (\ r \ n) o incluso mejor para preservar los finales de línea del archivo?

Nota: uso sed de unxutils: http://unxutils.sourceforge.net/

Bogdan Calmac
fuente
2
Las siguientes soluciones no funcionan en macOS.
William Entriken
Incluso llegué tan lejos y todavía no funcionóLC_ALL=C perl -i -e 'binmode $STDIN;undef $/;$_=<>;s|http://911coned.com|https://911coned.com|gm;print' education.html
William Entriken
Entonces, en realidad, el comando anterior funciona y acabo de descubrir un error en el git diffprograma.
William Entriken
1
Puede usar sed (sin opciones especiales) + unix2dos
mems

Respuestas:

143

Puede usar la -bopción de sed para que trate el archivo como binario. Esto solucionará el problema con sed de cygwin en Windows.

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

Si desea hacer coincidir el final de la línea, recuerde hacer coincidir, capturar y copiar el retorno de carro opcional.

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

Desde la página man de sed :

-b --binario

Esta opción está disponible en todas las plataformas, pero solo es efectiva cuando el sistema operativo hace una distinción entre archivos de texto y archivos binarios. Cuando se hace tal distinción, como es el caso de MS-DOS, Windows, Cygwin, los archivos de texto se componen de líneas separadas por un retorno de carro y un carácter de avance de línea, y sed no ve el final CR. Cuando se especifica esta opción, sed abrirá archivos de entrada en modo binario, por lo que no solicitará este procesamiento especial y considerará que las líneas terminan en un salto de línea.

Shlomo
fuente
5
Tenga en cuenta que esto no funciona con sed -icygwin (para mí), pero puede solucionarlo. Gracias por la actualización: las otras respuestas fueron la última palabra sobre este tema durante un tiempo.
harpo
Tenga en cuenta que esta opción no está disponible con sed en Mac.
Senthil Kumaran
21
Funciona para mí incluso con sed -i: es importante cómo escribirlo. Mientras sed -biy sed -i -btrabajo, sed -iblo hace sin trabajo: vea la página del manual para qué (utiliza el bcomo sufijo para la copia de seguridad).
Olaf Mandel
2
Uso:sed -bi 's/foo/bar/'
Kunal B.
2
No me funciona en Windows cygwin. En las líneas que sed hicieron el cambio, las terminaciones de línea son Unixy. El resto de líneas tienen finales de línea en forma de ventana. Por lo tanto, mi archivo obtuvo una mezcla de líneas con diferentes finales de línea.
truthadjustr
10

Puede intentar sustituir el \npara \r\nal final de su script existente de esta manera:

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

o quizás

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

Si ninguno de los dos anteriores funciona, tendrá que consultar la página de manual específica de su versión de sedpara ver si existe dicha opción. Tenga en cuenta que las versiones de * nix sedno no alterar las terminaciones de línea sin que se lo indique.

Otra alternativa es utilizar la cygwinversión de la sedcual no debería tener este comportamiento indeseable.

SiegeX
fuente
15
La versión cygwin tiene este comportamiento indeseable.
harpo
2
Si el archivo contiene \ n ( 0x0A) y \ r \ n ( 0x0D 0x0A), esta solución propuesta (de volver a inyectar siempre el \ r) lo rompe.
Vlad
Esto me funciona usando MSYS2 / MinGW. Gracias @SiegeX.
AntumDeluge
6

Alternativamente, (la versión cygwin de) perl -peno parece tener este problema.

buscador
fuente
sed en MacOS no tiene la opción -b y tiene problemas similares a los descritos en la pregunta original. La alternativa de perl no tiene este problema, así que gracias por su sugerencia. sed -i -e 's/<img[^>]*\/>//g' *.xmlreemplaza los finales de línea por '\ n' perl -i -p -e 's/<img[^>]*\/>//g' *.xmlconserva los finales de línea originales
Guruniverse
2

Gnuwin se puede suprimir para estropear las nuevas líneas (win-> unix) si solo especifica el modificador -b y redirecciona. Usar el interruptor -i (en línea) lo estropeará.

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

Buckley
fuente
1
Ver una versión con -imodo de trabajo en mi respuesta .
Vadzim
2

Descubrí que sed-4.4.exedesde https://github.com/mbuilov/sed-windows es pura victoria, ya que

  • utiliza finales de línea CRLF de Windows en modo predeterminado
  • conserva los finales de línea originales en el -bmodo
  • funciona correctamente con in-situ -iel modo
  • también ofrece un -zmodo con \0delimitadores en lugar de \nque a veces también puede ser útil

Consulte también la lista de opciones sed y la lista de todos los puertos sed de Windows .

Tenga en cuenta que GnuWin32 sed 4.2.1 hace finales de línea corruptos en -biel modo y no tiene -zel modo en absoluto.

Vadzim
fuente