Eu tenho um grande projeto para o qual estou tentando encontrar diretórios que não contenham um *_out.csv
arquivo. Eu olhei para outras respostas semelhantes e acho que estou quase lá.
O problema que estou enfrentando é que eu só quero procurar em diretórios que prosseguem analysis/
, mas também não quero procurar em alguns diretórios específicos que também procedem à análise.
Eu configurei um pequeno problema de exemplo:
$ tree
.
├── case1
│ ├── analysis
│ │ ├── test1
│ │ │ ├── gold
│ │ │ └── test1_out.csv
│ │ └── test2
│ └── doc
└── case2
├── analysis
│ ├── test3
│ │ └── gold
│ └── test4
│ └── test4_out.csv
└── doc
12 directories, 2 files
Não quero procurar em diretórios intitulados */doc/*
ou */gold/*
. Meu comando atual é:
find . -type d -not -name "doc" -not -name "gold" '!' -exec test -e "{}/*_out.csv" ';' -print
O que resulta em:
.
./case1
./case1/analysis
./case1/analysis/test1
./case1/analysis/test2
./case2
./case2/analysis
./case2/analysis/test3
./case2/analysis/test4
Minha saída ideal seria
./case1/analysis/test2
./case2/analysis/test3
Então, como você pode ver, meu find
comando atual está excluindo os diretórios doc
e gold
, mas não está excluindo os diretórios que possuem um *_out.csv
arquivo e também não excluindo os diretórios que não prosseguem analysis/
.
Então você quer procurar nos diretórios do formulário
*/analysis
, excluindo certos subdiretórios.Em vez de pesquisar tudo em
.
, pesquise apenas em*/analysis
.Para excluir um subdiretório, use
-prune
. Esta é uma ação que diz ao find para não percorrer esse subdiretório recursivamente.Finalmente, para testar se existe um arquivo que corresponde a um padrão, você precisa invocar um shell. Você está invocando
test
diretamente defind
, mastest
não faz correspondência de padrões, portanto, está apenas testando a existência de um arquivo cujo nome contém um*
caractere literal. Invoquesh
, passando o nome do diretório como argumento:-exec sh -c '…' {} \;
. No código sh, expanda um curinga para gerar a lista de arquivos correspondentes e verifique se existe pelo menos um arquivo existente.(Presumo que não haja links simbólicos pendentes cujo nome termine com
_out.csv
.)Sua tarefa é uma duplicata desta pergunta . A mesma estratégia funcionará:
Encontre todos os seus arquivos *_out.csv, retire o nome base e unifique a lista.
Encontre todos os diretórios que você espera que tenham arquivos *_out.csv e remova as entradas na lista 1 da lista da etapa 2.
Este script faz isso, com descritores de saída:
Condensado um pouco, isso poderia ser apenas: