Eliminar el retorno de carro en Unix
-
03-07-2019 - |
Pregunta
¿Cuál es la forma más sencilla de eliminar todos los retornos de carro? \r
de un archivo en Unix?
Solución
Asumiré que te refieres a retornos de carro ( CR , "\r"
, 0x0d
) en los extremos de las líneas en lugar de solo a ciegas dentro de un archivo (puede que los tenga en medio de cadenas por todo lo que sé). Usando este archivo de prueba con un CR al 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 sed
no está disponible para usted, entonces ed
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 <=> no está disponible para usted, entonces <=> lo hará de una 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 :-)
Otros consejos
tr -d '\r' < infile > outfile
Ver tr (1)
Vieja escuela:
tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
Hay una utilidad llamada dos2unix que existe en muchos sistemas y se puede instalar fácilmente en la mayoría.
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 simple r
, y eliminará todas las minúsculas /g
. Es por eso que la respuesta dada anteriormente en 2009 por Rob no funciona.
Y agregar el modificador <=> asegura que incluso múltiples <=> serán eliminados, y no solo el primero.
sed -i s/\r// <filename>
o algo así; consulte 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 quiere decir el 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 reemplazar \r\n
en su lugar. Los avances de línea desnuda (nueva línea) en Linux / Unix son \n
.
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.
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 lo recomiendo encarecidamente también.Sólo estoy proporcionando más detalles.
Si está instalado, salte al siguiente paso.Si aún no está instalado, recomendaría instalarlo a través de yum
como:
yum install dos2unix
Entonces puedes usarlo como:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
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
intente esto para convertir el archivo DOS en archivo Unix:
archivo fromdos
Si está utilizando un sistema operativo (como OS X) que no tiene el comando dos2unix
pero tiene un intérprete de Python (versión 2.5+), este comando es equivalente al comando source ~/.bashrc
:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
Esto maneja tanto los archivos con nombre en la línea de comando como las canalizaciones y redireccionamientos, al igual que <=>. 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 ejecute <=> en la sesión actual) podrá usar el nombre <=> en la línea de comando de la misma manera que en los otros ejemplos.
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 de estudio visual), 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 su 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 código visual como su reemplazo para notepad ++ en un entorno Linux y está listo para comenzar.
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)
Aunque es una publicación anterior, recientemente me encontré con el mismo problema. Como tenía todos los archivos para cambiar el nombre dentro de / tmp / blah_dir / ya que cada archivo en este directorio tenía & Quot; / r & Quot; carácter final (que muestra "? " al final del archivo), por lo que hacerlo en forma de script fue lo único que se me ocurrió.
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ó.
Lo intenté con " awk " finalmente que funcionó donde usé " \ r " como delimitador y tomó la primera parte :
truco es:
echo ${filename}|awk -F"\r" '{print $1}'
Debajo del fragmento de script que utilicé (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)
simplemente puedes hacer esto:
$ echo $(cat input) > output