Suchen nach menschenlesbaren Dateien

Suchen nach menschenlesbaren Dateien

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

Wie dem auch sei, 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 verwende ich diefindBefehl. Ich kann die Dateien finden, die den beiden letzten Kriterien entsprechen:

find . -size 1033c ! -executable

Ich weiß jedoch nicht, wie ich nicht menschenlesbare Dateien ausschließen kann. Lösungen, die ich für diese Herausforderung gefunden habe, verwenden den -readableTestparameter, aber ich glaube nicht, dass das funktioniert. -readableprüft nur die Berechtigungen der Dateien und nicht deren Inhalt, während in der Herausforderungsbeschreibung nach einer ASCII-Datei oder etwas Ähnlichem gefragt wird.

Antwort1

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

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

Die Frage ist jedoch nicht so einfach, wie sie klingt. „Menschenlesbar“ ist ein schrecklich vager Begriff. Vermutlich meinen Sie Text. OK, aber welche Art von Text? Nur ASCII mit lateinischen 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. Sehen wir uns nun an, was filesie ausmacht:

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

findDer obige Befehl findet also nur file1(nehmen wir für dieses Beispiel an, dass diese Dateien 1033 Zeichen haben). Sie könnten den Befehl erweitern, findum nach der Zeichenfolge zu suchen text:

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

Mit dem -wwerden grepnur Zeilen gedruckt, in denen textals alleinstehendes Wort vorkommt. Dassollenkommt Ihrem Wunsch ziemlich nahe, aber ich kann nicht garantieren, dass es keinen anderen Dateityp gibt, dessen Beschreibung auch die Zeichenfolge enthalten könnte text.

Antwort2

Es wird zwar -exechauptsächlich verwendet, um etwas mit den gefundenen Dateien zu tun, kann aber 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, grepdass ein Wert ungleich Null zurückgegeben wird, wenn das Muster nicht gefunden wurde, und sh -c "COMMAND"das Ergebnis der Auswertung zurückgegeben wird (sofern es gültig ist). Es werden also nur Dateien gedruckt, die file <filename>etwas ausgeben, das mit endet text, z. B. „UTF-8 Unicode-Text“ oder „ASCII-Text“, aber nicht „Nicht-ISO-erweiterter ASCII-Text mit Escape-Sequenzen“.

In einer einzigen Zeile ist es am Ende sogar kürzer als wenn man darübergeht xargs:

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

Denken Sie daran, dass Sie sh -c 'file {} | grep "text$"'durch jeden benutzerdefinierten Befehl ersetzen können. Wenn Sie etwas sehr Komplexes prüfen möchten, ist es möglicherweise eine bessere Idee, 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 der Verlauf Ihrer Shell:

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

Antwort3

Es gibt nur 1 Datei mit 1033einer Größe von Bytes.

bandit5@bandit:~$ find -size 1033c
./inhere/maybehere07/.file2
bandit5@bandit:~$ 

Warum 1033cund warum nicht 1033? Siehe manSeite

   -size n[cwbkMG]
          File uses n units of space, rounding up.  The following suffixes can be used:

          `b'    for 512-byte blocks (this is the default if no suffix is used)

          `c'    for bytes

          `w'    for two-byte words

          `k'    for Kilobytes (units of 1024 bytes)

          `M'    for Megabytes (units of 1048576 bytes)

          `G'    for Gigabytes (units of 1073741824 bytes)

Überprüfen Sie es mit ls -leinem fileBefehl, und Sie erhalten die vollständige Antwort.

bandit5@bandit:~$ ls -l ./inhere/maybehere07/.file2
-rw-r----- 1 root bandit5 1033 May  7 20:15 ./inhere/maybehere07/.file2
bandit5@bandit:~$ 
bandit5@bandit:~$ file ./inhere/maybehere07/.file2
./inhere/maybehere07/.file2: ASCII text, with very long lines
bandit5@bandit:~$ 
  1. für Menschen lesbar ( ASCII text)
  2. 1033 Bytes groß (auch in ls -lder Ausgabe)
  3. nicht ausführbar ( -rw-r-----)

Antwort4

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

verwandte Informationen