encontra o arquivo “corrompido”, aninhando um se dentro de um comando find

1

Estou tentando encontrar arquivos "corruptos" dentro de uma estrutura de diretórios, ou seja, arquivos que o comando de arquivo interpretaria como "dados". Aqui está o comando que estou tentando executar, mas falha:

$ find . -type f -exec if [[ $(file \{} | cut -f2 -d':') == " data" ]] \; then echo " \{}  is CORRUPT" \; else echo " \{} is DATA" \; fi \;
find: paths must precede expression: then

Alguém sabe o que estou fazendo de errado aqui?

Eu percebo que nunca vi um if dentro de um parâmetro -exec . É mesmo possível?

Basicamente, estou tentando encontrar arquivos que correspondam a esse critério (o arquivo relata como "dados", embora não identifique um tipo de arquivo específico) e, em seguida, liste-os para que eu possa analisar antes de removê-los.

    
por lolinux 06.03.2016 / 09:58

2 respostas

3

Você precisa de um shell para interpretar as construções if/then/else ou executar esses pipelines (embora você não precise deles aqui):

find . -type f -exec sh -c '
  for file do
    case $(file -b "$file") in
      (data) printf "%s is CORRUPT\n" "$file";;
         (*) printf "%s is DATA\n" "$file";;
    esac
  done' sh {} +

(como na sua pergunta, ele imprime "CORRUPT" quando file diz data . Não sei ao certo o que você quis dizer).

Não importa o que você fizer, não inclua {} no código de shell, como outros sugeriram! Isso seria muito perigoso (e btw não portátil), como por exemplo, um arquivo chamado $(rm -rf "$HOME") faria com que você removesse todo o seu diretório pessoal.

    
por 06.03.2016 / 11:55
0

Não é a resposta exata para o seu título (aninhando um se dentro de um achado), mas para todos os propósitos, uma solução melhor do que inserir um script de shell inteiro dentro de um achado.

Observe também que, dentro de um genérico sh , os testes [[ não funcionam e o [ não corresponde a um padrão no lado direito do = . Ou use uma correspondência de regex == ~ como eu acredito que você precisa. Então, você precisaria de um shell bash, o que não faz muito sentido se você já estiver dentro de um shell bash. Em qualquer caso, isso é mais rápido do que iniciar um novo shell:

#!/bin/bash
while IFS= read -rd '' file; do
    if [[ $(file "$file" | cut -f2 -d':') =~ " data" ]]; then
        printf "%s is CORRUPT\n" "$file"
    else
        printf "%s is DATA\n" "$file"
    fi
done < <(find . -type f -print0)

Advertência: alterei seu == para a = ~ supondo que você deseja corresponder o texto ' data' em uma imagem PNG (ou algo semelhante):

$ file TrueTable-1.png| cut -f2 -d':'
PNG image data, 405 x 292, 8-bit colormap, non-interlaced

Por favor, faça um comentário se esta suposição não for verdadeira.

    
por 06.03.2016 / 16:34