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 find
Befehl 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 -readable
Testparameter, aber ich denke nicht, dass dies funktioniert. -readable
Betrachtet nur die Berechtigungen der Dateien und nicht deren Inhalt, während in der Beschreibung der Herausforderung nach einer ASCII-Datei oder ähnlichem gefragt wird.
Antworten:
Ja, Sie können mit
find
nach nicht ausführbaren Dateien der richtigen Größe suchen und dannfile
nach ASCII suchen . Etwas wie: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:
Dies sind alles Texte und für Menschen lesbar. Nun wollen wir sehen, was sie
file
ausmacht:So wird der
find
obige Befehl nur findenfile1
(für dieses Beispiel stellen wir uns vor, dass diese Dateien 1033 Zeichen hatten). Sie können das erweiternfind
, um nach der Zeichenfolge zu suchentext
:Mit
-w
,grep
werden nur Zeilen gedruckt, in denentext
sich 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älttext
.quelle
Während
-exec
es 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:Denken Sie daran, dass ein
grep
Wert ungleich Null zurückgegeben wird, wenn das Muster nicht gefunden wurde, undsh -c "COMMAND"
dass das Ergebnis der Auswertung zurückgegeben wird (solange es gültig ist). Es werden also nur Dateien gedruckt, in denenfile <filename>
etwastext
ausgegeben 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
: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:Was auf lange Sicht einfacher zu pflegen ist als die Geschichte deiner Shell:
quelle
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.quelle
Sie müssen nur verwenden:
Sie erhalten die einzige Datei, die das Kennwort enthält.
quelle
Führen Sie einfach die folgenden Schritte für den Inhalt des Verzeichnisses aus:
quelle
Bitte probieren Sie diese kombinierten Befehle. es funktioniert auf meiner Station.
quelle
Sie können dies versuchen
Ihre Herausforderung erlaubt nicht
grep
. Passwortdatei wird als "ASCII-Text mit sehr langen Zeilen" gemeldetquelle
Um die lesbaren Dateinamen herauszufiltern, können Sie den
[:print:]
( druckbaren ) Zeichenklassennamen verwenden. Weitere Informationen zu solchen Klassen finden Sie im Handbuch fürgrep
.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
file
Befehl verwenden, um den Dateiinhaltstyp zu bestimmen. Es wäre jedoch keine gute Idee,file
nach einer Pipe zu rennen , da dies die Anzeige des Dateinamens erschweren würde. Folgendes schlage ich vor:So funktioniert der
file
-part kurz :-exec
Prädikat wirdsh -c 'file -b $0 | grep -q text' FILENAME
für jedes ausgeführtFILENAME
, das alle vorherigen Bedingungen erfüllt (Typ, Größe, nicht ausführbar).sh
) das folgende kurze Skript aus :file -b $0 | grep -q text
und ersetzt es$0
durch den Dateinamen.file
Programm ermittelt den Inhaltstyp jeder Datei und gibt diese Informationen aus. Die-b
Option verhindert, dass der Name jeder getesteten Datei gedruckt wird.grep
filtert die Ausgabe desfile
Programms und sucht nach Zeilen, die "Text" enthalten . (Sehen Sie selbst, wie eine typische Ausgabe desfile
Befehls aussieht.)grep
nicht ausgibt den gefilterten Text, weil es die hat-q
(leise) Option gegeben. Ändern Sie einfach den Exit-Status in0
"true" (der gefilterte Text wurde gefunden) oder in "1" (was "error" bedeutet - der Text "text" wurde in der Ausgabe von nicht angezeigtfile
).grep
weitersh
an weitergeleitetfind
und ist das Endergebnis des gesamten-exec sh -c 'file $0 | grep -q text' {} \;
Tests.-print
Befehl ausgeführt (dh der Name der getesteten Datei wird gedruckt).quelle
quelle
erhalten Sie die Datei aus der Übung
quelle
Fan von einem Liner
quelle
wird Ihr Ergebnis erhalten
quelle