Encontre arquivos legíveis por humanos

Encontre arquivos legíveis por humanos

Estou tentando encontrar uma maneira eficiente de fazer onível 5 do desafio do bandido OverTheWire.

De qualquer forma, tenho vários arquivos e só existe um que atende aos seguintes critérios:

  • Legível por humanos
  • 1033 bytes de tamanho
  • Não executável

No momento, estou usando ofindcomando. Consigo encontrar os arquivos que correspondem aos dois últimos critérios:

find . -size 1033c ! -executable

No entanto, não sei como excluir arquivos não legíveis por humanos. As soluções que encontrei para esse desafio usam o -readableparâmetro test, mas não acho que funcione. -readableanalisa apenas as permissões dos arquivos, e não seu conteúdo, enquanto a descrição do desafio pede um arquivo ASCII ou algo parecido.

Responder1

Sim, você pode usar findpara procurar arquivos não executáveis ​​do tamanho certo e depois usar filepara verificar ASCII. Algo como:

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

A questão, porém, não é tão simples quanto parece. 'Legível por humanos' é um termo terrivelmente vago. Presumivelmente, você quer dizer texto. OK, mas que tipo de texto? Caractere latino apenas ASCII? Unicode completo? Por exemplo, considere estes três arquivos:

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

Tudo isso é texto e legível por humanos. Agora, vamos ver o que filefaz deles:

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

Portanto, o findcomando acima irá apenas encontrar file1(para este exemplo, vamos imaginar que esses arquivos tinham 1033 caracteres). Você pode expandir para findprocurar a string text:

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

Com o -w, grepimprimirá apenas as linhas textencontradas como uma palavra independente. Quedeveesteja bem próximo do que você deseja, mas não posso garantir que não exista outro tipo de arquivo cuja descrição também possa incluir a string text.

Responder2

Embora -execseja usado principalmente para fazer algo com os arquivos encontrados, também pode funcionar como um teste. Portanto, podemos adicioná-lo aos seus outros critérios:

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

Lembre-se, grepretorna diferente de zero quando o padrão não foi encontrado e sh -c "COMMAND"retornará o resultado da avaliação (desde que seja válido). Portanto, isso imprimirá apenas arquivos onde file <filename>cospe algo que termina com text, por exemplo, "Texto Unicode UTF-8" ou "Texto ASCII", mas não "Texto ASCII estendido não ISO, com sequências de escape".

Em uma única linha, acaba até ficando mais curto do que passar por cima xargs:

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

Lembre-se de que você pode substituir sh -c 'file {} | grep "text$"'por qualquer comando personalizado. Se você quiser verificar algo muito complexo, pode ser uma ideia melhor fornecer um script de shell e usá-lo:

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

que, a longo prazo, é mais fácil de manter do que o histórico do seu shell:

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

Responder3

Existe apenas 1 arquivo com 1033bytes de tamanho.

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

Por que 1033ce não 1033? Verifique a manpágina

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

Verifique com ls -lum filecomando e você obterá todas as respostas.

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. legível por humanos ( ASCII text)
  2. 1033 bytes de tamanho (também na ls -lsaída)
  3. não executável ( -rw-r-----)

Responder4

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

informação relacionada