2010-07-16 12 views

Antwort

56

Wenn Sie Perl verwenden möchten, tun Sie es wie folgt aus:

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

Detaillierte Erläuterung

Die folgende Erklärung jeden Teil des obigen Befehl deckt den Leser unter der Annahme, die nicht mit alles in der Lösung ...

  • perl

    den Perl-Interpreter ausführen. Perl ist eine Programmiersprache, die typischerweise auf allen Unix-ähnlichen Systemen verfügbar ist. Dieser Befehl muss an einer Shell-Eingabeaufforderung ausgeführt werden.

  • -p

    Die -p Flag teilt perl jede Zeile in der Eingabedatei iterieren, die spezifizierten Befehle ausführen (später beschrieben) in jeder Zeile, und dann das Ergebnis drucken. Es entspricht dem Wrapping Ihres Perl-Programms in while(<>) { /* program... */; } continue { print; }. Es gibt eine ähnliche -n Flagge, die das gleiche tut, aber den continue { print; } Block weglässt, also würden Sie das verwenden, wenn Sie Ihren eigenen Druck machen wollten.

  • -i

    Die -i Flag teilt Perl dass die Eingabedatei an Ort und Stelle und Ausgabe bearbeitet werden soll, sollte wieder in diese Datei gehen. Dies ist wichtig, um die Datei tatsächlich zu ändern. Wenn Sie dieses Flag auslassen, wird die Ausgabe in STDOUT geschrieben, die Sie dann in eine neue Datei umleiten können.

    Hinweis, die Sie nicht -i weglassen und STDOUT auf die Eingabedatei umleiten, da dies die Eingabedatei verprügeln, bevor es gelesen wurde. So funktioniert die Shell und hat nichts mit Perl zu tun. Die -i-Flagge funktioniert auf intelligente Weise.

    Perl und die Schale können Sie mehrere einzelne Zeichen Parameter zu einem kombinieren, weshalb wir -pi statt -p -i

    Die -i Flagge nimmt ein einziges Argument verwenden, die eine Dateierweiterung ist zu verwenden, wenn Sie möchten, Wenn Sie -i.bak verwendet haben, kopiert Perl die Eingabedatei in filename.bak, bevor Sie Änderungen vornehmen.In diesem Beispiel habe ich weggelassen ein Backup erstellen, da erwarte ich werde Sie Versionskontrolle verwenden sowieso :)

  • -e

    Die -e Flag teilt Perl, dass das nächste Argument ist ein komplettes Perl-Programm in einem gekapselten Zeichenfolge. Dies ist nicht immer eine gute Idee, wenn Sie ein sehr langes Programm haben, da dieses unlesbar wird, aber mit einem einzigen Befehlsprogramm, wie wir es hier haben, kann seine Kürze die Lesbarkeit verbessern.

    Hinweis, dass wir die -e Flagge mit der -i Flagge als sie beide nimmt in einem einzigen Argumente nicht kombinieren können, und Perl würde davon ausgehen, dass das zweite Flag das Argument, so zum Beispiel, wenn wir -ie <program> <filename> verwendet, perl würde annehmen, <program> und <filename> sind beide Eingabedateien und versuchen, <program>e und <filename>e unter der Annahme, dass e ist die Erweiterung, die Sie für die Sicherung verwenden möchten. Dies wird fehlschlagen, da <program> nicht wirklich eine Datei ist. Andersherum (-ei) würde auch nicht funktionieren, weil Perl versuchen würde, i als ein Programm auszuführen, das Kompilierung fehlschlagen würde.

  • s/.../.../

    Dies ist regex basiert Substitution Bediener Perl. Es nimmt vier Argumente auf. Der erste kommt vor dem Operator und wenn nicht angegeben, wird der Standardwert $_ verwendet. Die zweite und dritte sind zwischen den / Symbolen. Der vierte ist nach dem letzten / und ist in diesem Fall g.

    • $_ In unserem Code ist das erste Argument $_ die die variable Standardschleife ist in Perl. Wie oben erwähnt, umschließt das Flag -p unser Programm in while(<>), das eine while Schleife erstellt, die jeweils eine Zeile (<>) vom Eingang liest. Implizit wird diese Zeile $_ zugewiesen, und alle Befehle, die ein einzelnes Argument verwenden, verwenden dies, wenn sie nicht angegeben werden (z. B. wird nur der Aufruf print; tatsächlich in print $_; übersetzt). In unserem Code arbeitet der Operator s/.../.../ einmal in jeder Zeile der Eingabedatei.

    • [^[:ascii:]] Das zweite Argument ist das Muster, nach dem in der Eingabezeichenfolge gesucht werden soll. Dieses Muster ist ein regulärer Ausdruck, also ist alles, was in [] eingeschlossen ist, ein Klammerausdruck. Dieser Abschnitt ist wahrscheinlich der komplexeste Teil dieses Beispiels, weshalb wir ihn am Ende im Detail besprechen werden.

    • <empty string> Das dritte Argument ist die Ersetzungszeichenfolge, in unserem Fall die leere Zeichenfolge, da wir alle nicht-ASCII-Zeichen entfernen möchten.

    • g Das vierte Argument ist ein Modifikatorflag für den Substitutionsoperator. Das Flag g gibt an, dass die Ersetzung für alle Übereinstimmungen in der Eingabe global sein soll. Ohne dieses Flag wird nur die erste Instanz ersetzt.Andere mögliche Flags sind i für case insensitive Matches, s und m, die nur für mehrzeilige Strings relevant sind (wir haben hier einfache Strings), o, die angeben, dass das Muster vorkompiliert werden soll (was hier für lange Dateien nützlich sein könnte) und x, die angibt, dass das Muster Whitespace und Kommentare enthalten kann, um es lesbarer zu machen (aber wir sollten unser Programm nicht in einer einzelnen Zeile schreiben, wenn das der Fall ist).

  • filename

    Dies ist die Eingabedatei, die Nicht-ASCII-Zeichen enthält, die wir Streifen aus möchten.

[^[:ascii:]]

So, jetzt die [^[:ascii:]] näher diskutieren lassen.

Wie bereits erwähnt, gibt [] in einem regulären Ausdruck einen Klammerausdruck an, der der Regex-Engine ein einzelnes Zeichen in der Eingabe zuordnet, das mit einem der Zeichen in der Zeichengruppe innerhalb des Ausdrucks übereinstimmt. So passt zum Beispiel [abc] entweder a oder b oder c, und es wird nur ein einzelnes Zeichen übereinstimmen. Wenn ^ als erstes Zeichen verwendet wird, wird die Übereinstimmung invertiert, sodass [^abc] mit einem beliebigen Zeichen übereinstimmt, das kein a, b oder c ist.

Aber was ist mit [:ascii:] innerhalb der Klammer Ausdruck?

Wenn Sie ein Unix-basiertes System verfügbar haben, führen Sie in der Befehlszeile man 7 re_format aus, um die Manpage zu lesen. Wenn nicht, read the online version

[:ascii:] ist eine Charakter-Klasse, die den gesamten Satz von ascii Zeichen darstellt, aber diese Art von einer Zeichenklasse kann nur in einem Ausdruck in eckigen Klammern verwendet werden. Der richtige Weg, um dies zu verwenden, ist [[:ascii:]] und es kann wie oben mit dem abc Fall negiert oder in einem Klammerausdruck mit anderen Zeichen kombiniert werden, so dass zum Beispiel [éç[:ascii:]] alle ASCII-Zeichen sowie é und ç übereinstimmen, die nicht als ASCII sind, und [^éç[:ascii:]] werden alle Zeichen übereinstimmen, die nicht ASCII sind und auch nicht é oder ç.

+0

hat dies getan, bevor Sie Ihren Kommentar gelesen haben. – janar

+0

@bluesmoon Kannst du das durchbrechen und erklären, was passiert? –

+3

@JoshuaRobinson Ich habe die Antwort mit einer ausführlichen Erklärung bearbeitet. – bluesmoon

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

Angenommen, Sie möchten "Kontroll" -Zeichen und "druckbare" Zeichen beibehalten. Geige nach Bedarf.

+3

'tr -dc '\ 11 \ 12 \ 15 \ 40- \ 176' bereinigt- Datei 'Steuerzeichen können viele Dinge enthalten – user3338098

1

Meine two cents: Es kann nicht Ihr Problem lösen, aber es kann Ihnen einige Hinweise geben.

Der Befehl file teilt Ihnen die Dateicodierung mit, d. H. UTF, ASCII usw. und iconv kann eine Datei zwischen verschiedenen Codierungen konvertieren.

+1

iconv überraschenderweise entkleidet einige andere Sachen auch auf der XML-Datei .. ich habe iconv -f ascii -t ascii -c – janar

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

Dies ist genau das, was ich getan habe, um das Problem zu beheben. – janar

3

Sie können ein C-Programm wie folgt schreiben:

#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; 
} 

Hinweis: Fehlerprüfungen wurden der Einfachheit halber vermieden.

Kompilieren mit:

$ gcc -W source_code.c -o convert 

Run mit:

$ ./convert 
Verwandte Themen