it-swarm.com.de

Entfernen aller Nicht-ASCII-Zeichen aus einem Workflow (Datei)

Wie würde ich alle Nicht-ASCII-Zeichen aus einer Datei entfernen? Würde es einen bestimmten Befehl geben, um dies auszuführen?

grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...

Ich glaube, dies findet die Zeichen im Workflow, aber wie würde ich alle Instanzen der fraglichen Zeichen entfernen?

13
Mizole Ni

ASCII-Zeichen sind Zeichen im Bereich von 0 bis 177 (einschließlich Oktal) .

Verwenden Sie zum Löschen von Zeichen außerhalb dieses Bereichs in einer Datei

LC_ALL=C tr -dc '\0-\177' <file >newfile

Der Befehl tr ist ein Dienstprogramm, das mit einzelnen Zeichen arbeitet. Ersetzt sie entweder durch andere einzelne Zeichen (Transliteration), löscht sie oder komprimiert Läufe desselben Zeichens in ein einzelnes Zeichen.

Der obige Befehl würde aus file lesen und den geänderten Inhalt in newfile schreiben. Das -d Mit der Option tr löscht das Dienstprogramm Zeichen (anstatt sie zu transliterieren) und -c berücksichtigt Zeichen außerhalb des angegebenen Intervalls (anstelle von innerhalb).

LC_ALL=C stellt sicher, dass jeder Bytewert ein gültiges Zeichen bildet. Ohne sie würden einige tr-Implementierungen abgebrochen, wenn sie Folgen von Bytes finden würden, die in der Zeichenkodierung des Gebietsschemas keine gültigen Zeichen bilden.


Verwenden Sie, um die Originaldatei durch die geänderte zu ersetzen

LC_ALL=C tr -dc '\0-\177' <file >newfile &&
mv newfile file

Dadurch wird die neue Datei in den Namen der alten Datei umbenannt, nachdem tr erfolgreich abgeschlossen wurde. Wenn tr nicht erfolgreich abgeschlossen wird, weil die Originaldatei nicht gelesen oder nicht in die neue Datei geschrieben werden konnte, bleibt die Originaldatei unverändert.

Verwenden Sie alternativ, um die Metadaten (Berechtigungen usw.) der Originaldatei so weit wie möglich beizubehalten

cp file tmpfile &&
LC_ALL=C tr -dc '\0-\177' <tmpfile >file &&
rm tmpfile
27
Kusalananda

Mit Perl

Perl -pi -e 's/[^[:ascii:]]//g'
14
user88036

Wenn Sie nur einen regulären Ausdruck benötigen: [\x00-\x7F], die Sie auf mehrere Dienstprogramme anwenden können:

<file LC_ALL=C   sed   's/[^\o0-\o177]//g'      # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^\0-\177]/,"");print}'
<file            Perl  -pe 's/[^[:ascii:]]//g;'
<file LC_ALL=C   tr    -dc '\0-\177'

Verstehen Sie, dass sed, awk und Perl "Textdateien" erwarten, wie sie in Unix definiert sind. In diesem Fall funktionieren alle gut. Insbesondere fügt awk eine nachfolgende neue Zeile hinzu (unabhängig davon, ob sie in der Quelldatei vorhanden ist oder nicht) (mit printf werden ALLE neuen Zeilen in der Eingabe entfernt). Das tr kann mit jedem Dateityp verwendet werden. Allerdings ist der NUL (\0) ist kein gültiges Zeichen in einer POSIX-Textdatei und sollte vermieden werden:

Die Zeilen enthalten keine NUL-Zeichen ...

Tatsächlich würden viele Steuerzeichen unter bestimmten Bedingungen andere Probleme erzeugen.
Also, wahrscheinlich brauchst du [\x07-\x0d\x20-\x7e]

<file LC_ALL=C   sed   's/[^\o007-\o015\o040-\o176]//g'            # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^\0-\15\40-\176]/,"");print}'
<file            Perl  -pe 's/[^\x{7}-\x{d}\x{20}-\x{7e}]//g;'
<file LC_ALL=C   tr    -dc '\7-\15\40-\176'

Der Bereich 7-13 (dezimal) ist \a\b\t\n\v\f\r (in Ordnung).
Ein ähnlicher (wahrscheinlich portablerer) Bereich könnte als [^[:space:][:print:]] (similar because it doesn't include\a\b` - Glocke und Rücktaste--).

<file LC_ALL=C   sed   's/[^[:space:][:print:]]//g'  # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^[:space:][:print:]]/,"");print}'
<file            Perl   -pe 's/[^[:space:][:print:]]//g;'
<file LC_ALL=C   tr     -dc '[:space:][:print:]'

Verbunden:
Regex any ASCII Zeichen
Perl-Lösung
Posix-Textdatei

9
Isaac