Existe uma maneira de encontrar arquivos contendo apenas caracteres não imprimíveis?

6

Eu tenho um programa que está se comportando mal e criou um número de arquivos com apenas alguns caracteres não imprimíveis. Se eu fosse catar os arquivos, não vejo nada (já que são caracteres não imprimíveis). No entanto, esses arquivos não serão exibidos se eu usar algo como -empty ou -size 0 com o comando find .

Alguém sabe de uma maneira de procurar arquivos contendo apenas caracteres não imprimíveis?

    
por Joshc1107 05.03.2012 / 16:16

2 respostas

9

Com o GNU grep (e várias outras implementações do grep), você pode procurar por arquivos que não contenham nenhum caractere imprimível. A opção -L significa listar os arquivos que não contêm uma correspondência. [[:print:]] (sim, existem dois pares de colchetes) corresponde a um caractere imprimível; a definição de caractere imprimível depende da sua localidade.

grep -L '[[:print:]]' -- *

Observe que isso inclui arquivos vazios (como mindas apontou ).

Para excluir todos eles (revise a grep output primeiro para ter certeza de que você está excluindo os arquivos corretos), supondo que os nomes dos arquivos não contenham nenhum caractere de nova linha:

grep -L '[[:print:]]' -- * |
while IFS= read -r filename; do
  if [ -f "$filename" ] && [ -s "$filename" ]; then
    rm "$filename"
  fi
done

ou equivalentemente (observe que isso também exclui arquivos vazios)

set +f; IFS='
' # split at newlines, turn off globbing
rm -- $(set -f; grep -L '[[:print:]]' -- *)
set -f; unset IFS

Observe que os comandos acima produzirão mensagens de erro se houver subdiretórios no diretório atual (porque você estará chamando rm em um diretório - não chame rm -r !). Em zsh, você pode usar *(.L+0) em vez de * para corresponder apenas a arquivos não vazios comuns e não precisa se preocupar com caracteres especiais em nomes de arquivos (exceto em linhas novas):

IFS=$'\n'
rm -- $(grep -L '[[:print:]]' -- *(.))
unset IFS

Com apenas ferramentas POSIX, grep -l '[[:print:]]' -- * mostra os arquivos que você deseja manter (exceto arquivos vazios).

Ou você pode iterar pelos arquivos; isso é mais claro, e com certeza não causa nenhum problema com chacters especiais (mas ignora arquivos de ponto), mas teoricamente (mas provavelmente não mensuravelmente) mais lento.

for x in *; do
  if [ -f "$x" ] && [ -s "$x" ] && ! grep -q '[[:print:]]' <"$x"; then
    rm -- "$x"
  fi
done
    
por 05.03.2012 / 18:07
4

Sua melhor aposta é provavelmente usar file . Tente isto:

find . -type f -exec file {} + | grep ": data"

Agora, isso não captura os arquivos que, aleatoriamente, têm o número mágico correto no início, mas é bem provável que a maioria dos outros métodos não os detectem de qualquer maneira.

Outras maneiras de encontrar esses arquivos:

  • Hora da última modificação: find -mmin 5 = 5 mins ago
  • Tamanho, não necessariamente zero: find -size -4k = menor que 4096 bytes
por 05.03.2012 / 16:38