Eliminar retorno de carro en Unix


Respuestas:


261

Voy a asumir que los retornos de carro medias ( CR, "\r", 0x0d) en los extremos de las líneas en lugar de a ciegas dentro de un archivo (que puede tener en el medio de cadenas por lo que sé). Usando este archivo de prueba con un CRal final de la primera línea solamente:

$ cat infile
hello
goodbye

$ cat infile | od -c
0000000   h   e   l   l   o  \r  \n   g   o   o   d   b   y   e  \n
0000017

dos2unix es el camino a seguir si está instalado en su sistema:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Si por alguna razón dos2unixno está disponible para usted, sedlo hará:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Si por alguna razón sedno está disponible para usted, edlo hará de manera complicada:

$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Si no tiene ninguna de esas herramientas instaladas en su caja, tiene mayores problemas que tratar de convertir archivos :-)


13
\rfunciona solo con GNU sed, de lo contrario puede hacer esto:sed `echo "s/\r//"`
lapo

15
Ni sedtampoco lo echoreconozco \ren MacOs. En este caso solo printf "\r"parece funcionar.
Steve Powell

30
Para dar más detalles sobre el comentario de @ steve: En una Mac, use lo siguiente: sed "s/$(printf '\r')\$//"
mklement0

77
Para solucionar el problema en Mac, también puede prefijar la cadena de sed de comillas simples de la siguiente $manera: sed $'s@\r@@g' |od -c (pero si lo reemplazara con \n, necesitaría escapar)
nhed

1
No estoy 100% seguro, pero para OS X, usar CTRL-V + CTRL-Men lugar de \rparece que podría funcionar.

240
tr -d '\r' < infile > outfile

Ver tr (1)


44
No es genial: 1. no funciona en el lugar, 2. puede reemplazar \ r también no en EOL (que puede o no ser lo que desea ...).
Tomasz Gandor

10
1. La mayoría de las herramientas de Unixy funcionan de esa manera, y generalmente es la forma más segura de hacer las cosas, ya que si lo arruinas aún tienes el original. 2. La pregunta como se indicó es eliminar los retornos de carro, no convertir las terminaciones de línea. Pero hay muchas otras respuestas que podrían servirle mejor.
Henrik Gustafsson

1
Si trno admite el \rescape, intente '\015'o tal vez un literal '^M'(en muchos shells en muchas terminales, ctrl-V ctrl-M producirá un carácter literal ctrl-M).
tripleee

Entonces, ¿cómo se cambia cuando quieres outfile = infile?
Christopher

3
@donlan, respuesta tardía pero se suelen utilizar algo como: someProg <in >out && mv out in.
paxdiablo

38

Vieja escuela:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

32

La forma más simple en Linux es, en mi humilde opinión,

sed -i 's/\r$//g' <filename>

Las comillas fuertes alrededor del operador de sustitución 's/\r//'son esenciales . Sin ellos, el shell interpretará \rcomo un escape + r y lo reducirá a un plano r, y eliminará todas las minúsculas r. Es por eso que la respuesta dada por Rob en 2009 no funciona.

Y agregar el /gmodificador asegura que incluso múltiples \rserán eliminados, y no solo el primero.



7

sed -i s/\r// <filename>o algo así; ver man sedo la gran cantidad de información disponible en la web sobre el uso de sed.

Una cosa a destacar es el significado preciso de "retorno de carro" en lo anterior; si realmente se refiere al carácter de control único "retorno de carro", entonces el patrón anterior es correcto. Si se refería, de manera más general, a CRLF (retorno de carro y avance de línea, que es cómo se implementan los avances de línea en Windows), entonces probablemente desee reemplazarlo \r\n. Los avances de línea desnuda (nueva línea) en Linux / Unix son \n.


Estoy tratando de usar -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt que no funciona. "Tigre Leon."
Suvasis

¿debemos tomar eso como que estás en una Mac? Me he dado cuenta de Darwin sed parece tener diferentes comandos y conjuntos de características por defecto que la mayoría de las versiones de Linux ...
jsh

44
Para su información, s/\r//no parece eliminar los retornos de carro en OS X, sino que elimina los rcaracteres literales . No estoy seguro de por qué eso es todavía. ¿Quizás tiene algo que ver con la forma en que se cita la cadena? Como solución alternativa, el uso CTRL-V + CTRL-Men lugar de \rparece funcionar.

6

Si es un usuario de Vi, puede abrir el archivo y eliminar el retorno de carro con:

:%s/\r//g

o con

:1,$ s/^M//

Tenga en cuenta que debe escribir ^ M presionando ctrl-v y luego ctrl-m.


2
No es genial: si el archivo tiene CR en cada línea (es decir, es un archivo DOS correcto), vim lo cargará con filetype = dos, y no mostrará ^M-s en absoluto. Eludir esto es un montón de pulsaciones de teclas, que no es para lo que está hecho vim;). Simplemente iría por sed -i, y luego '-e' s / \ r $ // g 'para limitar la eliminación a CR en EOL.
Tomasz Gandor

6

Una vez más una solución ... Porque siempre hay una más:

perl -i -pe 's/\r//' filename

Es agradable porque está en su lugar y funciona en todos los sabores de Unix / Linux con el que he trabajado.


3

Alguien más lo recomienda dos2unixy yo también lo recomiendo encarecidamente. Solo estoy proporcionando más detalles.

Si está instalado, salte al siguiente paso. Si aún no está instalado, recomendaría instalarlo mediante yum:

yum install dos2unix

Entonces puedes usarlo como:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt

2

Si está utilizando un sistema operativo (como OS X) que no tiene el dos2unixcomando pero tiene un intérprete de Python (versión 2.5+), este comando es equivalente al dos2unixcomando:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Esto maneja ambos archivos con nombre en la línea de comando, así como tuberías y redireccionamientos, al igual que dos2unix. Si agrega esta línea a su archivo ~ / .bashrc (o un archivo de perfil equivalente para otros shells):

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

... la próxima vez que inicie sesión (o se ejecute source ~/.bashrcen la sesión actual) podrá usar el dos2unixnombre en la línea de comandos de la misma manera que en los otros ejemplos.


2

Aquí está la cosa,

%0des el carácter de retorno de carro. Para que sea compatible con Unix. Necesitamos usar el siguiente comando.

dos2unix fileName.extension fileName.extension


1

intente esto para convertir el archivo DOS en archivo Unix:

archivo fromdos


1

Para UNIX ... He notado que dos2unix eliminó los encabezados Unicode de mi archivo UTF-8. Bajo git bash (Windows), el siguiente script parece funcionar bien. Utiliza sed. Tenga en cuenta que solo elimina los retornos de carro al final de las líneas y conserva los encabezados Unicode.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"

1

Si está ejecutando un entorno X y tiene un editor adecuado (código visual de estudio), entonces seguiría la recomendación:

Código de Visual Studio: cómo mostrar finales de línea

Simplemente vaya a la esquina inferior derecha de la pantalla, el código de Visual Studio le mostrará tanto la codificación del archivo como la convención de final de línea seguida del archivo, y solo con un simple clic puede cambiar eso.

Simplemente use el código visual como su reemplazo para notepad ++ en un entorno Linux y ya está listo.


O use Notepad++el comando 's Edit / EOL Conversion / Unix (LF)en su sistema Windows antes de copiar el archivo a su sistema Linux.
Jesse Chisholm

1

Eliminación \ren cualquier sistema UNIX®:

La mayoría de las soluciones existentes en esta pregunta son específicas de GNU y no funcionarían en OS X o BSD; las siguientes soluciones deben trabajar en muchos más sistemas UNIX, y en cualquier concha, de tcshque sh, aún así funcionar incluso en GNU / Linux, también.

Probado en OS X, OpenBSD y NetBSD en tcsh, y en Debian GNU / Linux en bash.


Con sed:

En tcshun OS X, el siguiente sedfragmento podría usarse junto con printf, como sedni lo echomaneja \rde manera especial como lo hace GNU:

sed `printf 's/\r$//g'` input > output

Con tr:

Otra opción es tr:

tr -d '\r' < input > output

Diferencia entre sedy tr:

Parece que trconserva la falta de una nueva línea final del archivo de entrada, mientras que seden OS X y NetBSD (pero no en OpenBSD o GNU / Linux) inserta una nueva línea final al final del archivo, incluso si falta la entrada final \ro \nal final del archivo.


Pruebas:

Aquí hay algunas pruebas de muestra que podrían usarse para garantizar que esto funcione en su sistema, usando printfy hexdump -C; alternativamente, od -ctambién podría usarse si falta su sistema hexdump:

% printf 'a\r\nb\r\nc' | hexdump -C
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
% 

0

He usado Python para ello, aquí mi código;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)

0

Aunque es una publicación anterior, recientemente me encontré con el mismo problema. Como tenía que cambiar el nombre de todos los archivos dentro de / tmp / blah_dir / ya que cada archivo en este directorio tenía el carácter final "/ r" (mostrando "?" Al final del archivo), por lo que solo podía pensar en hacerlo en forma de script.

Quería guardar el archivo final con el mismo nombre (sin arrastrar ningún carácter). Con sed, el problema era el nombre de archivo de salida, que necesitaba mencionar algo más (que no quería).

Probé otras opciones como se sugiere aquí (no se considera dos2unix debido a algunas limitaciones) pero no funcionó.

Finalmente intenté con "awk", que funcionó donde usé "\ r" como delimitador y tomé la primera parte :

el truco es:

echo ${filename}|awk -F"\r" '{print $1}'

Debajo del fragmento de script que usé (donde tenía todos los archivos tenía "\ r" como carácter final en la ruta / tmp / blah_dir /) para solucionar mi problema:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

Nota: Este ejemplo no es muy exacto, aunque cercano a lo que trabajé (Mencionando aquí solo para dar una mejor idea de lo que hice)


0

Hice este script de shell para eliminar el carácter \ r. Funciona en solaris y red-hat:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0

-1

simplemente puedes hacer esto:

$ echo $(cat input) > output

No sé por qué alguien dio '-1'. Esta es una respuesta perfectamente buena (y la única que funcionó para mí).
FractalSpace

1
Oh, lo siento, fui yo. ¡Espera, mira, realmente no funciona para '\ r'!
Viacheslav Rodionov

1
@FractalSpace ¡Esta es una idea terrible! Destruye completamente todo el espacio en el archivo y deja todo el contenido del archivo sujeto a interpretación por parte del shell. Pruébelo con un archivo que contenga una línea a * b...
Tom Fenech
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.