2010-07-26 24 views
40

Quiero eliminar todos los caracteres no ASCII de un archivo en su lugar.Eliminar caracteres no ASCII de CSV

Encontré una solución con tr, pero creo que necesito volver a escribir ese archivo después de la modificación.

Necesito hacerlo en su lugar con un rendimiento relativamente bueno.

¿Alguna sugerencia?

+0

se puede proporcionar un enlace a un revestimiento con tr? –

+0

El OP probablemente (?) Significa caracteres no imprimibles (ctrl-c, número Unicode U + 0002, es un carácter ASCII). La pregunta también debe especificar la configuración regional: sin esa información, uno podría (¿debería?) Asumir que se refería a la configuración regional "C". Una respuesta ingenua sería eliminar cualquier byte mayor que 0x7f, lo que preservaría los caracteres que no son imprimibles en la configuración regional C, pero que son caracteres ASCII perfectamente legítimos. Estoy bajando la votación debido a estas razones que la hacen demasiado vaga. – Juan

Respuesta

30
# -i (inplace) 

sed -i 's/[\d128-\d255]//g' FILENAME 
+2

tuvo que cambiarlo a sed -i 's/[\ d128- \ d255] // g' NOMBRE DE ARCHIVO y funcionó .. gracias – Sujit

+0

@Sujit: Tenga en cuenta que 'sed -i' todavía crea un archivo intermedio. Simplemente lo hace detrás de la escena. –

+0

@Dennis - entonces, ¿cuál sería la mejor solución? – Sujit

57

Un oneliner Perl haría: perl -i.bak -pe 's/[^[:ascii:]]//g' <your file>

-i dice que el archivo se va a editar in-situ, y la copia de seguridad va a ser salvado con la extensión .bak.

+1

Éste es también utilizable con 'stdin' como entrada. – h3xStream

+2

La solución perl es más rápida que la solución sed. Intentar actualizar un archivo de 122 GB usando sed llevó 3 horas, mientras que Perl me tomó menos de 2 horas. – Roger

+0

No pude conseguir que la solución 'sed' funcionara en mi entorno (Ubuntu gnu sed 4.2.2) pero funcionó a las mil maravillas. –

3

Como alternativa a sed o perl, puede considerar usar las clases de caracteres ed (1) y POSIX.

Nota: ed (1) lee el archivo en la memoria para editarlo en el lugar, por lo que para archivos muy grandes que usted debe usar sed -i ..., Perl -i ...

# see: 
# - http://wiki.bash-hackers.org/doku.php?id=howto:edit-ed 
# - http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes 

# test 
echo $'aaa \177 bbb \200 \214 ccc \254 ddd\r\n' > testfile 
ed -s testfile <<< $',l' 
ed -s testfile <<< $'H\ng/[^[:graph:][:space:][:cntrl:]]/s///g\nwq' 
ed -s testfile <<< $',l' 
11
sed -i 's/[^[:print:]]//' FILENAME 

Además, este actúa como dos2unix

+9

No funciona. [: print:] no es lo mismo que ASCII. Hay muchos caracteres imprimibles que no son ASCII. –

+0

También falta el modificador g. Solo se eliminará el primer carácter no imprimible. – proski

+0

@JasonC También hay muchos caracteres ASCII no imprimibles. Es probable que la pregunta original estuviera mal formada. – Juan

10

me encontré con la siguiente solución que se va a trabajar:

perl -i.bk -pe 's/[^[:ascii:]]//g;' filename 
2
awk '{ sub("[^a-zA-Z0-9\"[email protected]#$%^&*|_\[](){}", ""); print }' MYinputfile.txt > pipe_out_to_CONVERTED_FILE.txt 
4

Estoy usando un sistema busybox muy mínimo, en el cual no hay soporte para rangos en tr o clases de caracteres POSIX, así que tengo que hacerlo de la manera anticuada. Aquí está la solución con sed, despojando a todos los caracteres no ASCII no imprimibles a partir del archivo:

sed -i 's/[^a-zA-Z 0-9`[email protected]#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' FILE 
-1

aprecio los consejos que se encuentran en este sitio.

Pero, en mi Windows 10, tuve que usar comillas dobles para que esto funcione ...

sed -i "s/[\d128-\d255]//g" FILENAME

Noté estas cosas ...

  1. Para FILENAME la totalidad ruta \ nombre necesita ser cotizada Esto no funcionó - %TEMP%\"FILENAME" Esto hizo - %TEMP%\FILENAME"

  2. hojas de sed detrás de los archivos temporales en el directorio actual, llamada sed *

+0

Nota: esta respuesta funciona con gnu sed, pero no es portátil para otras versiones de sed (por ejemplo, bsd). Teniendo en cuenta los efectos secundarios mencionados en esta respuesta, parece una versión compilada de ventanas extrañas que intenta emular a gnu sed. O el usuario está enturbiando el agua con problemas de shell no relacionados. – Juan

3

Esto funcionó para mí:

sed -i 's/[^[:print:]]//g' 
+0

Todavía estoy obteniendo caracteres Unicode como 007F en mi terminal. –

+0

@KatasticVoyage ¿Cuál es su configuración regional (LANG, LC_CTYPE)? – Juan

1

Trate tr en lugar de sed

tr -cd '[:print:]' < file.txt 
+1

El OP mencionó específicamente que no quería usar tr (porque quería una conversión "in situ" que sed -i pretende ser- realmente escribe en un archivo temporal y cambia el nombre detrás de escena). Entonces esta respuesta no ayuda al OP. PERO ... para aquellos que quieran usar tr, es posible que desee preservar nuevas líneas (la versión 20180228 que se muestra aquí no). Sin embargo, un simple tweak conserva las líneas nuevas y los retornos de carro: 'tr -cd '[: print:] \ n \ r' Juan

Cuestiones relacionadas