¿Cuál es la forma más sencilla de eliminar todos los retornos de carro \r
de un archivo en Unix?
¿Cuál es la forma más sencilla de eliminar todos los retornos de carro \r
de un archivo en Unix?
Respuestas:
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 dos2unix
no está disponible para usted, sed
lo 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 sed
no está disponible para usted, ed
lo 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 :-)
\r
funciona solo con GNU sed, de lo contrario puede hacer esto:sed `echo "s/\r//"`
sed
tampoco lo echo
reconozco \r
en MacOs. En este caso solo printf "\r"
parece funcionar.
sed "s/$(printf '\r')\$//"
$
manera: sed $'s@\r@@g' |od -c
(pero si lo reemplazara con \n
, necesitaría escapar)
tr -d '\r' < infile > outfile
Ver tr (1)
tr
no admite el \r
escape, 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).
outfile = infile
?
someProg <in >out && mv out in
.
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á \r
como 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 /g
modificador asegura que incluso múltiples \r
serán eliminados, y no solo el primero.
sed -i s/\r// <filename>
o algo así; ver man sed
o 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
.
s/\r//
no parece eliminar los retornos de carro en OS X, sino que elimina los r
caracteres 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-M
en lugar de \r
parece funcionar.
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.
^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.
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.
Alguien más lo recomienda dos2unix
y 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
Si está utilizando un sistema operativo (como OS X) que no tiene el dos2unix
comando pero tiene un intérprete de Python (versión 2.5+), este comando es equivalente al dos2unix
comando:
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 ~/.bashrc
en la sesión actual) podrá usar el dos2unix
nombre en la línea de comandos de la misma manera que en los otros ejemplos.
Aquí está la cosa,
%0d
es el carácter de retorno de carro. Para que sea compatible con Unix. Necesitamos usar el siguiente comando.
dos2unix fileName.extension fileName.extension
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"
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.
Notepad++
el comando 's Edit / EOL Conversion / Unix (LF)
en su sistema Windows antes de copiar el archivo a su sistema Linux.
\r
en 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 tcsh
que 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
.
sed
:En tcsh
un OS X, el siguiente sed
fragmento podría usarse junto con printf
, como sed
ni lo echo
maneja \r
de manera especial como lo hace GNU:
sed `printf 's/\r$//g'` input > output
tr
:Otra opción es tr
:
tr -d '\r' < input > output
sed
y tr
:Parece que tr
conserva la falta de una nueva línea final del archivo de entrada, mientras que sed
en 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 \r
o \n
al final del archivo.
Aquí hay algunas pruebas de muestra que podrían usarse para garantizar que esto funcione en su sistema, usando printf
y hexdump -C
; alternativamente, od -c
tambié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
%
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)
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
simplemente puedes hacer esto:
$ echo $(cat input) > output
a * b
...