Encuentra archivos legibles por humanos

Encuentra archivos legibles por humanos

Estoy tratando de encontrar una manera eficiente de hacer elnivel 5 del desafío de bandidos OverTheWire.

De todos modos, tengo un montón de archivos y solo hay uno que cumple con los siguientes criterios:

  • Legible por humanos
  • 1033 bytes de tamaño
  • No ejecutable

Ahora mismo estoy usando elfinddominio. Puedo encontrar los archivos que coinciden con los dos últimos criterios:

find . -size 1033c ! -executable

Sin embargo, no sé cómo excluir archivos no legibles por humanos. Las soluciones que encontré para ese desafío utilizan el -readableparámetro de prueba, pero no creo que funcione. -readablesolo mira los permisos de los archivos, y no su contenido, mientras que la descripción del desafío solicita un archivo ASCII o algo así.

Respuesta1

Sí, puede utilizar findpara buscar archivos no ejecutables del tamaño correcto y luego utilizarlos filepara comprobar si hay ASCII. Algo como:

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

La cuestión, sin embargo, no es tan sencilla como parece. "Legible por humanos" es un término terriblemente vago. Presumiblemente, te refieres a texto. Vale, pero ¿qué tipo de texto? ¿Solo caracteres latinos ASCII? Unicode completo? Por ejemplo, considere estos tres archivos:

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

Todos estos son texto y legibles por humanos. Ahora, veamos qué filehace con ellos:

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

Entonces, el findcomando anterior solo encontrará file1(para este ejemplo, imaginemos que esos archivos tuvieran 1033 caracteres). Podrías expandir el findpara buscar la cadena text:

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

Con -w, grepsolo imprimirá líneas donde textse encuentre como palabra independiente. Esodeberíaser bastante cercano a lo que desea, pero no puedo garantizar que no haya otro tipo de archivo cuya descripción también pueda incluir la cadena text.

Respuesta2

Si bien -execse usa principalmente para hacer algo con los archivos encontrados, también puede actuar como prueba. Por lo tanto, podemos agregarlo a sus otros criterios:

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

Recuerde, grepdevuelve un valor distinto de cero cuando no se encontró el patrón y sh -c "COMMAND"devolverá el resultado de la evaluación (siempre que sea válido). Por lo tanto, esto solo imprimirá archivos que file <filename>escupan algo que termine con text, por ejemplo, "texto Unicode UTF-8" o "texto ASCII", pero no "texto ASCII extendido no ISO, con secuencias de escape".

En una sola línea, incluso termina siendo más corto que repasar xargs:

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

Tenga en cuenta que puede reemplazarlo sh -c 'file {} | grep "text$"'con cualquier comando personalizado. Si desea verificar algo muy complejo, podría ser una mejor idea proporcionar un script de shell y usarlo en su lugar:

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

que, a la larga, es más fácil de mantener que el historial de tu shell:

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

Respuesta3

Sólo hay 1 archivo con 1033bytes de tamaño.

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

¿Por qué 1033cy no 1033? revisa la manpagina

   -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)

Verifícalo con ls -lun filecomando y obtendrás todas las respuestas.

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. legible por humanos ( ASCII text)
  2. 1033 bytes de tamaño (también en ls -lsalida)
  3. no ejecutable ( -rw-r-----)

Respuesta4

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

información relacionada