2010-07-16 18 views

Respuesta

56

Si desea utilizar Perl, hacerlo de esta manera:

perl -pi -e 's/[^[:ascii:]]//g' filename 

Explicación detallada

La siguiente explicación cubre cada parte del comando anterior suponiendo que el lector está familiarizado con cualquier cosa en la solución ...

  • perl

    ejecuta el intérprete perl. Perl es un lenguaje de programación que normalmente está disponible en todos los sistemas de tipo Unix. Este comando debe ejecutarse en un indicador de shell.

  • -p

    La bandera -p dice Perl para iterar sobre cada línea en el archivo de entrada, ejecute los comandos especificados (descrito más adelante) en cada línea, y luego imprimir el resultado. Es equivalente a envolver su programa perl en while(<>) { /* program... */; } continue { print; }. Hay una bandera similar -n que hace lo mismo, pero omite el bloque continue { print; }, por lo que lo usaría si quisiera hacer su propia impresión.

  • -i

    La bandera -i dice Perl que el archivo de entrada se va a editar en su lugar y la salida debe ir de nuevo en ese archivo. Esto es importante para realmente modificar el archivo. Si omite este indicador, se escribirá el resultado en STDOUT, que luego podrá redireccionar a un nuevo archivo.

    Nota que no se puede omitir -i y redirigir STDOUT al archivo de entrada ya que esto clobber el archivo de entrada antes de que se ha leído. Así es como funciona el caparazón y no tiene nada que ver con perl. La bandera -i funciona de forma inteligente.

    Perl y la cáscara le permiten combinar múltiples parámetros de caracteres individuales en una sola razón por la cual podemos utilizar -pi en lugar de -p -i

    El -i indicador toma un solo argumento, que es una extensión de archivo a utilizar si desea para hacer una copia de seguridad del archivo original, por lo que si usó -i.bak, entonces perl copiará el archivo de entrada a filename.bak antes de realizar cambios.En este ejemplo he omitido la creación de una copia de seguridad porque espero que va a utilizar el control de versiones de todos modos :)

  • -e

    La bandera -e dice Perl que el próximo argumento es un programa Perl completa encapsulada en una cuerda. Esto no siempre es una buena idea si tienes un programa muy largo, ya que puede ser ilegible, pero con un único programa de comando como el que tenemos aquí, su concisión puede mejorar la legibilidad.

    Nota que no podemos combinar la bandera -e con la bandera -i ya que ambos toman en un solo argumento, y Perl supondría que el segundo indicador es el argumento, por lo que, por ejemplo, si usamos -ie <program> <filename>, perl supondría <program> y <filename> son ambos archivos de entrada e intentan crear <program>e y <filename>e asumiendo que e es la extensión que desea usar para la copia de seguridad. Esto fallará ya que <program> no es realmente un archivo. A la inversa (-ei) tampoco funcionaría, ya que Perl trataría de ejecutar i como un programa, lo que fallaría en la compilación.

  • s/.../.../

    Esto se basa expresiones regulares operador de sustitución de Perl. Toma en cuatro argumentos. El primero viene antes que el operador, y si no se especifica, usa el valor predeterminado de $_. El segundo y el tercero se encuentran entre los símbolos /. El cuarto es después de la final / y es g en este caso.

    • $_ En nuestro código, el primer argumento es $_ que es la variable de bucle por defecto en Perl. Como se mencionó anteriormente, la bandera -p envuelve nuestro programa en while(<>), que crea un bucle while que lee una línea a la vez (<>) desde la entrada. Asigna implícitamente esta línea al $_, y todos los comandos que toman en un solo argumento usarán esto si no se especifica (ej .: simplemente llamando al print; se traducirá realmente al print $_;). Entonces, en nuestro código, el operador s/.../.../ opera una vez en cada línea del archivo de entrada.

    • [^[:ascii:]] El segundo argumento es el patrón a buscar en la cadena de entrada. Este patrón es una expresión regular, por lo que cualquier elemento incluido dentro de [] es una expresión de corchetes. Esta sección es probablemente la parte más compleja de este ejemplo, por lo que la discutiremos en detalle al final.

    • <empty string> El tercer argumento es la cadena de reemplazo, que en nuestro caso es la cadena vacía, ya que queremos eliminar todos los caracteres no ascii.

    • g El cuarto argumento es un indicador modificador para el operador de sustitución. El indicador g especifica que la sustitución debe ser global en todas las coincidencias de la entrada. Sin esta bandera, solo la primera instancia será reemplazada.Otros posibles indicadores son i para coincidencias insensibles a mayúsculas y minúsculas, s y m que solo son relevantes para cadenas de varias líneas (aquí tenemos cadenas de una sola línea), o que especifica que el patrón debe precompilarse (lo que podría ser útil aquí para archivos largos) y x que especifica que el patrón podría incluir espacios en blanco y comentarios para hacerlo más legible (pero no deberíamos escribir nuestro programa en una sola línea si ese es el caso).

  • filename

    Este es el archivo de entrada que contiene caracteres no ASCII que nos gustaría que se deben eliminar.

[^[:ascii:]]

Así que ahora vamos a discutir [^[:ascii:]] con más detalle.

Como se mencionó anteriormente, [] en una expresión regular especifica una expresión de paréntesis, que le dice al motor de expresiones regulares que coincida con un solo carácter en la entrada que coincida con cualquiera de los caracteres del conjunto de caracteres dentro de la expresión. Por lo tanto, por ejemplo, [abc] coincidirá ya sea con a, o con b o con c, y coincidirá con un solo carácter. El uso de ^ como primer personaje invierte la coincidencia, por lo que [^abc] coincidirá con cualquier carácter que no sea a, b o c.

Pero, ¿qué hay de [:ascii:] dentro de la expresión del paréntesis?

Si tiene un sistema basado en Unix disponible, ejecute man 7 re_format en la línea de comando para leer la página de manual. Si no es así, read the online version

[:ascii:] es una clase de caracteres que representa el conjunto completo de caracteres ascii, pero este tipo de una clase de caracteres sólo se puede utilizar dentro de una expresión entre corchetes. La forma correcta de usar esto es [[:ascii:]] y puede negarse como en el caso abc anterior o combinarse dentro de una expresión de corchete con otros caracteres, por ejemplo, [éç[:ascii:]] coincidirá con todos los caracteres ASCII y también con é y é y ç que no son ascii, y [^éç[:ascii:]] coincidirá con todos los caracteres que no son ascii y tampoco é o ç.

+0

acaba de hacer esto antes de ver tu comentario. – janar

+0

@bluesmoon ¿Puedes analizar esto y explicar qué está pasando? –

+3

@JoshuaRobinson He editado la respuesta con una explicación detallada. – bluesmoon

8
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file 

Eso es suponiendo que desea conservar los caracteres de "control" y los caracteres "imprimibles". Violín según sea necesario.

+3

'tr -dc '\ 11 \ 12 \ 15 \ 40- \ 176' limpiado- los personajes de control de archivos pueden incluir muchas cosas – user3338098

1

Mi two cents: Puede que no resuelva su problema, pero puede darle algunos consejos.

El comando file indica que la codificación del archivo, es decir, UTF, ASCII, etc. y iconv puede convertir un archivo entre diferentes codificaciones.

+1

iconv Sorprendentemente despojaron de otras cosas también en el archivo xml ... hice iconv -f ascii -t ascii -c – janar

5
perl -pe's/[[:^ascii:]]//g' <input.txt> output.txt 
+1

Esto es exactamente lo que hice para solucionar el problema. – janar

3

se puede escribir un programa en C así:

#include <stdio.h> 
#include <ctype.h> 

int main(int argc, char **argv) 
{ 
    FILE *fin = fopen("source_file", "rb"); 
    FILE *fout = fopen("target_file", "w"); 
    int c; 
    while ((c = fgetc(fin)) != EOF) { 
     if (isprint(c)) 
      fputc(c, fout); 
    } 
    fclose(fin); 
    fclose(fout); 
    return 0; 
} 

Nota: comprobaciones de errores se evitaron por simplicidad.

Compilar con:

$ gcc -W source_code.c -o convert 

Ejecutar con:

$ ./convert 
Cuestiones relacionadas