Finden Sie lesbare Dateien


14

Ich versuche, einen effizienten Weg zu finden, um Level 5 der OverTheWire-Banditen-Herausforderung zu meistern .

Wie auch immer, ich habe eine Menge Dateien, und es gibt nur eine, die die folgenden Kriterien erfüllt:

  • Für Menschen lesbar
  • 1033 Bytes groß
  • Nicht ausführbar

Im Moment benutze ich den findBefehl und kann die Dateien finden, die den 2 letzten Kriterien entsprechen:

find . -size 1033c ! -executable

Ich weiß jedoch nicht, wie ich nicht von Menschen lesbare Dateien ausschließen soll. Lösungen, die ich für diese Herausforderung gefunden habe, verwenden den -readableTestparameter, aber ich denke nicht, dass dies funktioniert. -readableBetrachtet nur die Berechtigungen der Dateien und nicht deren Inhalt, während in der Beschreibung der Herausforderung nach einer ASCII-Datei oder ähnlichem gefragt wird.


1
Wie definieren Sie für Menschen lesbar? Nicht binär?
Terdon

1
Dateibefehl ist dein Freund :)
Romeo Ninov

Möglicherweise Duplikat von: stackoverflow.com/questions/14505218/…
zuazo

2
Der Mensch ist eine der intelligentesten bekannten Arten der Erde. Sie sind auch die einzigen, die sich mit Computern auskennen. Sie können die meisten Dateien lesen, sofern sie den Typ herausfinden und die Verschlüsselungsschlüssel für verschlüsselte Dateien erhalten.
Stéphane Chazelas

1
SPOILER ALARM!!
Dan Bolser

Antworten:


16

Ja, Sie können mit findnach nicht ausführbaren Dateien der richtigen Größe suchen und dann filenach ASCII suchen . Etwas wie:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

Die Frage ist jedoch nicht so einfach, wie es sich anhört. "Menschenlesbar" ist ein schrecklich vager Begriff. Vermutlich meinst du Text. OK, aber welche Art von Text? Nur lateinisches ASCII-Zeichen? Vollständiger Unicode? Betrachten Sie beispielsweise diese drei Dateien:

$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo

Dies sind alles Texte und für Menschen lesbar. Nun wollen wir sehen, was sie fileausmacht:

$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX shell script, ASCII text executable

So wird der findobige Befehl nur finden file1(für dieses Beispiel stellen wir uns vor, dass diese Dateien 1033 Zeichen hatten). Sie können das erweitern find, um nach der Zeichenfolge zu suchen text:

find . -type f -size 1033c ! -executable -exec file {} + | grep -w text

Mit -w, grepwerden nur Zeilen gedruckt, in denen textsich ein eigenständiges Wort befindet. Das sollte Ihrem Wunsch ziemlich nahe kommen, aber ich kann nicht garantieren, dass es keinen anderen Dateityp gibt, dessen Beschreibung möglicherweise auch die Zeichenfolge enthält text.


4

Während -execes meistens verwendet wird, um etwas mit den gefundenen Dateien zu tun, kann es auch als Test dienen. Daher können wir es zu Ihren anderen Kriterien hinzufügen:

find . \
  -size 1033c \
  -not -executable \
  -exec sh -c 'file {} | grep "text$"' \;

Denken Sie daran, dass ein grepWert ungleich Null zurückgegeben wird, wenn das Muster nicht gefunden wurde, und sh -c "COMMAND"dass das Ergebnis der Auswertung zurückgegeben wird (solange es gültig ist). Es werden also nur Dateien gedruckt, in denen file <filename>etwas textausgegeben wird, das mit "UTF-8 Unicode-Text" oder "ASCII-Text" endet , nicht jedoch "Nicht-ISO-Extended-ASCII-Text mit Escape-Sequenzen".

In einer einzelnen Zeile endet es sogar kürzer als beim Übergehen xargs:

find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;

Denken Sie daran, dass Sie durch sh -c 'file {} | grep "text$"'jeden benutzerdefinierten Befehl ersetzen können. Wenn Sie nach etwas sehr Komplexem suchen möchten, ist es möglicherweise besser, ein Shell-Skript bereitzustellen und dieses stattdessen zu verwenden:

find . -size 1033c -not -executable -exec is_human_readable.sh {} \;

Was auf lange Sicht einfacher zu pflegen ist als die Geschichte deiner Shell:

#!/bin/sh
file "$@" | grep "text$" > /dev/null

Nett! Beachten Sie jedoch, dass beim Abgleichen text$als Shell-Skripte erkannte Elemente ausgeschlossen werden. Alles, was mit einem Shebang zu tun hat, wird als Drehbuch identifiziert und ist für den Menschen perfekt lesbar.
Terdon

@terdon true, aber Skripte sind in der Regel ausführbar: D. Allerdings sollte ein richtiges Skript auch PDFs erkennen. Ist ein PDF-Dokument, das ein Bild enthält, für Menschen lesbar ? Ist eine PNG-Datei mit Text lesbar ? Wahrscheinlich. Ich denke, ein vollständiger Test wird… eine Herausforderung sein.
Zeta


1

Sie müssen nur verwenden:

find inhere -size 1033c

Sie erhalten die einzige Datei, die das Kennwort enthält.


Warum gibt + 1033c mehr Dateien zurück? Ist das wie ein Gleichheitszeichen?
Szeitlin

1

Führen Sie einfach die folgenden Schritte für den Inhalt des Verzeichnisses aus:

$ file -- *
-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data
$ cat -- \-file07
<output>

0
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: '{print $1}'

Bitte probieren Sie diese kombinierten Befehle. es funktioniert auf meiner Station.


0

Sie können dies versuchen

find . -size 1033c ! -executable -exec file {} +

Ihre Herausforderung erlaubt nicht grep. Passwortdatei wird als "ASCII-Text mit sehr langen Zeilen" gemeldet


0

Um die lesbaren Dateinamen herauszufiltern, können Sie den [:print:]( druckbaren ) Zeichenklassennamen verwenden. Weitere Informationen zu solchen Klassen finden Sie im Handbuch für grep.

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

Bei einem zweiten Gedanken bezieht sich die "für Menschen lesbare" Anforderung möglicherweise auf den Inhalt der Datei anstelle ihres Namens. Mit anderen Worten, Sie würden nach Textdateien suchen . Das ist etwas kniffliger. Wie @D_Bye in einem Kommentar vorgeschlagen hat, sollten Sie dann den fileBefehl verwenden, um den Dateiinhaltstyp zu bestimmen. Es wäre jedoch keine gute Idee, filenach einer Pipe zu rennen , da dies die Anzeige des Dateinamens erschweren würde. Folgendes schlage ich vor:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

So funktioniert der file-part kurz :

  • Das -execPrädikat wird sh -c 'file -b $0 | grep -q text' FILENAMEfür jedes ausgeführt FILENAME, das alle vorherigen Bedingungen erfüllt (Typ, Größe, nicht ausführbar).
  • Für jede dieser Dateien führt eine shell ( sh) das folgende kurze Skript aus : file -b $0 | grep -q textund ersetzt es $0durch den Dateinamen.
  • Das fileProgramm ermittelt den Inhaltstyp jeder Datei und gibt diese Informationen aus. Die -bOption verhindert, dass der Name jeder getesteten Datei gedruckt wird.
  • grepfiltert die Ausgabe des fileProgramms und sucht nach Zeilen, die "Text" enthalten . (Sehen Sie selbst, wie eine typische Ausgabe des fileBefehls aussieht.)
  • Aber grepnicht ausgibt den gefilterten Text, weil es die hat -q(leise) Option gegeben. Ändern Sie einfach den Exit-Status in 0"true" (der gefilterte Text wurde gefunden) oder in "1" (was "error" bedeutet - der Text "text" wurde in der Ausgabe von nicht angezeigt file).
  • Der wahre / falsche Ausgangsstatus, von dem " " er kommt, wird von " " grepweiter shan weitergeleitet findund ist das Endergebnis des gesamten -exec sh -c 'file $0 | grep -q text' {} \;Tests.
  • Wenn der obige Test true zurückgibt , wird der -printBefehl ausgeführt (dh der Name der getesteten Datei wird gedruckt).

0
bandit4@bandit:~$ ls
inhere

bandit4@bandit:~$ file inhere/*


inhere/-file00: data
inhere/-file01: data
inhere/-file02: data
inhere/-file03: data
inhere/-file04: data
inhere/-file05: data
inhere/-file06: data
inhere/-file07: ASCII text
inhere/-file08: data
inhere/-file09: data

bandit4@bandit:~$ pwd 

/home/bandit4

bandit4@bandit:~$ cat /home/bandit4/inhere/-file07

koReBOKuIDDepwhWk7jZC0RTdopnAYKh
bandit4@bandit:~$ 

Benutze einfach file inhere / * und cat / home / bandit4 / inhere / -file07

0
find  -type f ! -executable -size 1033c

erhalten Sie die Datei aus der Übung


0
find . -type f -size 1033c ! -executable | xargs file | grep text

Fan von einem Liner


-1
du --human-readable | find -not -executable -size 1033c

wird Ihr Ergebnis erhalten

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.