it-swarm.com.de

So suchen Sie in einem Bash-Skript nach Unicode �

if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt
fi

Grundsätzlich, wenn die Datei "out.txt" irgendwo in der Datei "�" enthält, möchte ich, dass sie "funktioniert" wiedergibt UND wenn die Datei "out.txt" NICHT "�" irgendwo in der Datei enthält, dann möchte ich es zu cat out.txt

EDIT: Also hier ist was ich tue. Ich versuche, eine openssl-Entschlüsselung brutal zu erzwingen.

openssl enc gibt bei Erfolg 0 zurück, andernfalls ungleich Null. Hinweis: Sie erhalten falsch positive Ergebnisse, da AES/CBC nur anhand der richtigen Auffüllung feststellen kann, ob "Entschlüsselung funktioniert". Die Datei entschlüsselt also, aber es wird nicht das richtige Passwort sein, so dass es Kauderwelsch enthält. Ein häufiges Zeichen im Kauderwelsch ist "�". Ich möchte also, dass die do-Schleife weiterläuft, wenn die Ausgabe "�" enthält.

Hier ist mein Git-Link https://github.com/Raphaeangelo/OpenSSLCracker Hier ist das Skript

while read line
do
openssl aes-256-cbc -d -a -in $1 -pass pass:$line -out out.txt 2>out.txt >/dev/null && printf "==================================================\n"
if grep -q "�" out.txt
    then
        :
    else
        cat out.txt &&
            printf "\n==================================================" &&
            printfn"\npassword is $line\n" &&
            read -p "press return key to continue..." < /dev/tty; 
fi
done < ./password.txt

es zeigt mir immer noch die Ausgabe mit dem �-Zeichen darin

UPDATE: Gelöst

printf "Working..."

while read line
do
openssl aes-256-cbc -d -a -in $1 -pass pass:$line -out out.txt 2>out.txt >/dev/null
if file out.txt | grep -q 'out.txt: ASCII text'
    then
        printf "\n==================================================\n\n" &&
            cat out.txt &&
            printf "\n==================================================" &&
            printf "\npassword is $line\n" && 
            read -p "press return key to continue..." < /dev/tty;
    else
        : 
fi
done < ./password.txt
10
Stuart Sloan

grep ist das falsche Werkzeug für den Job.

Sie sehen das � U+FFFD REPLACEMENT CHARACTER nicht, weil es buchstäblich im Dateiinhalt enthalten ist, sondern weil Sie eine Binärdatei mit einem Tool betrachtet haben, das nur textbasierte Eingaben verarbeiten soll. Die Standardmethode zum Behandeln ungültiger Eingaben (d. H. Zufällige Binärdaten) besteht darin, alles, was im aktuellen Gebietsschema (höchstwahrscheinlich UTF-8) nicht gültig ist, durch U + FFFD zu ersetzen, bevor es auf den Bildschirm gelangt.

Das heißt, es ist sehr wahrscheinlich, dass ein Literal \xEF\xBF\xBD (Die UTF-8-Byte-Sequenz für das U + FFFD-Zeichen) niemals in der Datei vorkommt. grep sagt Ihnen zu Recht, dass es keine gibt.

Eine Möglichkeit, festzustellen, ob eine Datei eine unbekannte Binärdatei enthält, ist der Befehl file(1):

$ head -c 100 /dev/urandom > rubbish.bin
$ file rubbish.bin
rubbish.bin: data

Für jeden unbekannten Dateityp wird einfach data angezeigt. Versuchen

$ file out.txt | grep '^out.txt: data$'

um zu überprüfen, ob die Datei wirklich eine beliebige Binärdatei und damit höchstwahrscheinlich Müll enthält.

Wenn Sie sicherstellen möchten, dass out.txt Nur eine UTF-8-codierte Textdatei ist, können Sie alternativ iconv verwenden:

$ iconv -f utf-8 -t utf-16 out.txt >/dev/null
27
Boldewyn

TL; DR:

grep -axv '.*' out.txt 

lange Antwort

Beide vorliegenden Antworten sind äußerst irreführend und grundsätzlich falsch.

Holen Sie sich zum Testen diese beiden Dateien (von einem sehr angesehenen Entwickler: Markus Kuhn):

$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt

Demo

Das erste UTF-8-demo.txt Ist eine Datei, die zeigen soll, wie gut UTF-8 viele Sprachen, Mathematik, Braille und viele andere nützliche Zeichentypen darstellen kann. Werfen Sie einen Blick mit einem Texteditor (der utf-8 versteht) und Sie werden viele Beispiele und no Sehen.

Der Test, den eine Antwort vorschlägt: Um den Zeichenbereich auf \x00-\x7F Zu beschränken, wird fast alles in dieser Datei abgelehnt.
Das ist sehr falsch und entfernt keine , Da diese keine enthält .

Wenn Sie den in dieser Antwort empfohlenen Test verwenden, wird 72.5 % Aus der Datei entfernt:

$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058

Das ist (für die meisten praktischen Zwecke) die gesamte Datei. Eine Datei, die sehr gut gestaltet ist, um perfekt gültige Zeichen anzuzeigen.

Prüfung

Die zweite Datei soll mehrere Grenzfälle versuchen, um zu bestätigen, dass utf-8-Leser gute Arbeit leisten. Es enthält viele Zeichen, die dazu führen, dass ein '�' angezeigt wird. Die andere Antwortempfehlung (die ausgewählte) zur Verwendung von file schlägt bei dieser Datei jedoch grob fehl. Entfernen Sie nur ein Null-Byte (\0) (Was technisch als ASCII gültig ist) und ein \x7f Byte (DEL - Löschen) (was eindeutig ein ASCII Zeichen) ist auch) macht alle die Datei gültig für den Befehl file:

$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt 
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators

file erkennt nicht nur die vielen falschen Zeichen nicht, sondern erkennt und meldet auch nicht, dass es sich um eine UTF-8-Codierung handelt Datei.

Und ja, file kann UTF-8-codierten Text erkennen und melden:

$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text

Außerdem meldet file nicht als ASCII die meisten Steuerzeichen im Bereich von 1 bis 31. Es (file) meldet einige Bereiche als data:

$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data

Andere als ASCII text:

$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text

Als druckbarer Zeichenbereich (mit Zeilenumbrüchen):

$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text

Einige Bereiche können jedoch zu seltsamen Ergebnissen führen:

$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655

Das Programm file ist kein Werkzeug zum Erkennen von Text, sondern zum Erkennen von magic Zahlen in ausführbaren Programmen oder Dateien.

Die Bereiche file erkennen und der entsprechende Typ, den ich gefunden habe, waren:

  • Ein-Byte-Werte, meistens ASCII:

    {1..6} {14..26} {28..31} 127   :data
    {128..132} {134..159}          :Non-ISO extended-ASCII text
    133                            :ASCII text, with LF, NEL line terminators
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {160..255}                     :ISO-8859 text
    
  • Utf-8-codierte Bereiche:

    {1..6} {14..26} {28..31} 127   :data
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {128..132} {134..159}          :UTF-8 Unicode text
    133                            :UTF-8 Unicode text, with LF, NEL line terminators
    {160..255}                     :UTF-8 Unicode text
    {256..5120}                    :UTF-8 Unicode text
    

Eine mögliche Lösung liegt unten.


Vorherige Antwort.

Der Unicode-Wert für das Zeichen, das Sie veröffentlichen, lautet:

$ printf '%x\n' "'�"
fffd

Ja, das ist ein nicode-Zeichen 'REPLACEMENT CHARACTER' (U + FFFD) . Dies ist ein Zeichen, das verwendet wird, um alle ungültigen Unicode-Zeichen im Text zu ersetzen. Es ist eine "visuelle Hilfe", kein wirklicher Charakter. Um jede vollständige Zeile zu finden und aufzulisten, die ungültige [~ # ~] Unicode-Zeichen [~ # ~] enthält, verwenden Sie:

grep -axv '.*' out.txt 

wenn Sie jedoch nur feststellen möchten, ob ein Zeichen ungültig ist, verwenden Sie:

grep -qaxv '.*' out.txt; echo $?

Wenn das Ergebnis 1 Ist, ist die Datei sauber, andernfalls ist sie Null 0.


Wenn Sie gefragt haben, wie Sie das Zeichen Finden, verwenden Sie Folgendes:

➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�

Oder wenn Ihr System UTF-8-Text korrekt verarbeitet, einfach:

➤ echo "$a" | grep -oP '�'
�
5
Isaac

Diese sehr frühe Antwort war für den ursprünglichen Beitrag, der lautete:

So suchen Sie in einem Bash-Skript nach Unicode �

if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt  fi

Grundsätzlich, wenn die Datei "out.txt" irgendwo in der Datei "�" enthält, möchte ich, dass sie "funktioniert" wiedergibt UND wenn die Datei "out.txt" NICHT "�" irgendwo in der Datei enthält, dann möchte ich es zu cat out.txt

Versuchen

grep -oP "[^\x00-\x7F]"

mit einem if .. then Aussage wie folgt:

if grep -oP "[^\x00-\x7F]" file.txt; then
    echo "grep found something ..."
else
    echo "Nothing found!"
fi

Erläuterung????:

  • -P, --Perl-regexp: PATTERN ist ein regulärer Perl-Ausdruck
  • -o, --only-matching: Zeigt nur den Teil einer Zeile an, der mit PATTERN übereinstimmt
  • [^\x00-\x7F] ist eine Regex, die einem einzelnen Nicht-ASCII-Zeichen entspricht.
  • [[:ascii:]] - entspricht einem einzelnen ASCII char
  • [^[:ascii:]] - Entspricht einem einzelnen Nicht-ASCII-Zeichen

in bash

LC_COLLATE=C grep -o '[^ -~]' file
3
user88036