Encontre diretórios que contenham mais de um arquivo da mesma extensão

1

Estou usando o Debian 8.0 e gostaria, por exemplo, de encontrar diretórios que contenham mais de 1% do arquivo.mkv. Eu tentei isso e falhou:

find -type d -exec find {} -name '*.mkv' | wc -l\;

Existe um Q & A semelhante aqui no SuperUser , que eu não consegui adaptar. Isso não funcionou para mim:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; find '{}' -name '*.mkv' | wc -l" \; |   awk '$NF>=2'

A mensagem de erro aponta para um erro de sintaxe:

bash: -c: line 0: syntax error near unexpected token '('

A razão para isso é que o diretório tem um nome como este:

Directory With Space and (Brackets)
    
por fswings 08.04.2015 / 23:53

4 respostas

1

Eu sugiro que você ordene encontrar para procurar todos os arquivos e imprimir o diretório que contém cada correspondência, para que você não precise se preocupar com a análise de strings estranhas. Em seguida, use o uniq para contar as duplicatas e o awk para filtrar no primeiro campo, imprimindo as ocorrências mais de uma vez. por exemplo,

find . -type f -iname '*.mkv' -printf '%h\n'|sort|uniq -c | awk '$1 > 1'
    
por 09.04.2015 / 00:18
2

Eu posso tentar algo assim:

 find dirname -type f -name '*.mkv' -print0 | xargs -0 -L 1 dirname | sort | uniq -c | egrep -v '^ *1 ' | sed 's/^ *[0-9]* //'

O resultado gera os nomes de todos os arquivos .mkv, então o xargs faz um dirname em tudo para extrair apenas o nome do diretório, classificar todos os itens, fazer com que o uniq forneça uma contagem de linhas repetidas e usar egrep remova os que possuem somente 1 * .mkv arquivo e, finalmente, remover as contagens usando o sed para fornecer uma lista de diretórios apenas.

BTW, -print0 está sendo usado para que o caractere especial filename não cause problemas xargs precisa que a opção -0 interprete a entrada corretamente nesse caso .. Como observado nos comentários, a exceção é, obviamente, um caractere de nova linha como parte do nome do arquivo que eu pessoalmente não encontrei. xargs precisa da opção -0 para interpretar a entrada corretamente nesse caso.

    
por 09.04.2015 / 00:22
0

Uma espécie de hack, mas é o que eu faria:

for dir in $(find . -type d)
do
  if [ $(ls -l "$dir" | grep '\.mkv$' | wc -l) -ge 2 ]
  then
    echo "$dir"
  fi
done

Como isso funciona:

  1. Localize todos os subdiretórios do diretório atual find . -type d e faça um loop sobre eles com cada diretório sendo salvo na variável dir
  2. Se o diretório contiver mais de 2 arquivos mkv, imprima o conteúdo de $dir

Atualização: Meu mal, eu esqueci o mais de 2 parte da sua pergunta. Isso deve ser corrigido usando -ge em vez de -eq (o acima já está corrigido)!

    
por 09.04.2015 / 00:11
0

Uma solução perl

perl -le 'use File::Find; find (sub {if(/\.mkv$/) {$d{$File::Find::dir}++}}, "."); END {for (sort keys %d) {print if $d{$_}>1}};'

Este código é semelhante aos outros. O treewalk (do diretório atual ".") Está contando o diretório sempre que encontrar um arquivo .mkv (armazenado no% d hash). Após a caminhada, todos os diretórios com mais de dois arquivos são impressos.

    
por 09.04.2015 / 00:44