Tenho alguns arquivos de resultados de experimentos com falha e seu conteúdo é exatamente um único \n
(nova linha).
Gostaria de listá-los todos (talvez com algo como find
ou grep
), para saber quais são os arquivos e depois excluí-los.
Tenho alguns arquivos de resultados de experimentos com falha e seu conteúdo é exatamente um único \n
(nova linha).
Gostaria de listá-los todos (talvez com algo como find
ou grep
), para saber quais são os arquivos e depois excluí-los.
Crie um arquivo de referência fora do caminho de pesquisa (estará
.
no exemplo):Agora temos um arquivo conhecido idêntico ao que você está procurando. Em seguida, compare todos os arquivos regulares no caminho de pesquisa (
.
aqui) com o arquivo de referência:-size 1c
não é necessário, pode ser omitido; é apenas para melhorar o desempenho. É um teste preliminar rápido que rejeita arquivos de tamanhos errados, sem gerar processos adicionais. Processos relativamente caroscmp …
serão criados apenas para arquivos do tamanho certo.-s
ficacmp
em silêncio . Não precisamos de sua saída, apenas do status de saída.--
é explicado aqui: O que significa "--" (traço duplo)? Na verdade, não é necessário em nosso caso de exemplo, ou seja, se o arquivo de referência for especificado como/tmp/reference
e o caminho de pesquisa for.
. Usei-o--
no caso de alguém escolher descuidadamente caminhos que, de outra forma, fariam com quecmp
se comportasse mal ou fracassassem; com--
isso deve funcionar.-exec
é usado como um teste, será bem-sucedido se e somente secmp
retornar o status de saída zero; e para um arquivo testado isso acontecerá se o arquivo for idêntico a/tmp/reference
. Dessa forma,find
você receberá os nomes dos caminhos dos arquivos idênticos ao arquivo de referência.O método pode ser usado para localizar arquivos com qualquer conteúdo fixo; você só precisa de um arquivo de referência com o conteúdo exato (e não se esqueça de ajustar
-size …
se for usá-lo;-size "$(</tmp/reference wc -c)c"
será útil). No nosso caso específicoecho
foi usado um simples para criar o arquivo porque ele imprime um caractere de nova linha, que é exatamente o conteúdo que você deseja encontrar.Para
find
tentar excluir cada arquivo correspondente, use-delete
(xor-exec rm -- {} +
) depois-print
.Procure arquivos com um único byte. Compare-os com o valor conhecido. Imprima e/ou exclua se corresponder
Opcionalmente, anexe
-delete
para excluir e remova-print
se desejar uma execução silenciosa.Com GNU
grep
, você pode-z
tratar o arquivo inteiro como uma única linha (-z
fazgrep
uso de NUL como o terminador de linha, portanto, desde que seus arquivos não contenham NUL,\0
ele tem o efeito de tratar o arquivo inteiro como um único linha). Se combinarmos isso com-l
apenas imprimir o nome do arquivo e-P
usar os PCREs\n
, podemos procurar por "linhas" que tenham apenas uma\n
e nada mais:Por exemplo, dados estes três arquivos:
Executar o
grep
acima dá:Você também pode torná-lo recursivo, usando a
globstar
opção bash (de manbash
):Então, por exemplo, nesta situação:
Ativar
globstar
e executargrep
encontrará**/*
ambos os arquivos inválidos (estou redirecionando o erro padrão porque o grep reclama de receber diretórios para pesquisar em vez de arquivos; tais erros são esperados e podem ser ignorados com segurança):Como alternativa, use
find
para pesquisar apenas arquivos:Com
zsh
:print -rC1
:print
vir
no1
C
olumnN
: nullglob: não reclame se não houver correspondência e,print
em vez disso, passe uma lista vazia para.D
: dotglob: não pule arquivos ocultos.
: apenas arquivos regulares (como-type f
infind
oufile
/f
inrawhide
).L1
: deL
inglês1
.e[code]
executa o código no arquivo para determinar se é uma correspondência$mapfile[$REPLY]
expande para o conteúdo do arquivo (cujo caminho está em$REPLY
).POSIXly, e evitando gerar um ou mais processos por arquivo (assumindo uma
sh
implementação whereread
,[
andprintf
are builtin, o que geralmente é o caso):(observe que, ao contrário do zsh acima, a lista não está classificada).
Com
rawhide
(lista também não classificada):Com
grep
implementações que podem lidar com arquivos não-texto (pelo menos bytes NUL e linhas não delimitadas), como GNUgrep
na localidade C, você também pode fazer:Procura arquivos com tamanho de exatamente um byte, onde o resultado da leitura do arquivo (em um shell) está vazio - sh remove as novas linhas das substituições de comandos.
Apenas para apresentar uma nova alternativa, no FreeBSD, isso poderia ser feito como:
No entanto, um hash md5, mesmo de um arquivo pequeno, é provavelmente um pouco mais caro do que um simples arquivo
cmp
.Tentei encontrar uma maneira de formular o
cmp
método usandobash
a substituição de comando (e BSDfind
), mas é um pouco desajeitado:Novamente, provavelmente um pouco mais caro criar o arquivo de nova linha várias vezes do que o método Kamil de criar o arquivo de referência uma vez e compará-lo repetidamente.