Eu tenho duas pastas com estruturas de subpastas semelhantes, que eu gostaria de comparar. Por exemplo:
A
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5
e
B
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text
Gostaria de listar todas as subpastas das A
quais são prefixos para uma subpasta B
e também listar as subpastas correspondentes B
. A saída esperada é
child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing
Um requisito secundário: se houver várias correspondências B
, deve ocorrer um erro / aviso.
Minha solução :
cd A
for f in `ls -d */`;
do
cd B;
new_dirs=(`ls -1d $f*`);
cd -;
if [ ${#new_dirs[@]} -eq 0 ]
then
## DO_Nothing
continue;
elif [ ${#new_dirs[@]} -gt 1 ]
then
echo "Multiple matches to $f";
continue;
else
echo "Unique Match found to $f -- ${new_dirs[0]}";
continue;
fi;
done
Problema:
Para os valores de $f
, que não possuem subpastas correspondentes B
, a construção da matriz está me causando um erro. por exemplo:
ls: não é possível acessar 'child-4 *': esse arquivo ou diretório não existe
Questão
- Como se livrar desses erros?
- Existe uma maneira melhor de atingir o (s) objetivo (s) do que aquele no meu código?
Desde já, obrigado!
diff -rq DIR1 DIR2
para comparar não apenas a estrutura de diretórios, mas o conteúdo do arquivo.Respostas:
A melhor maneira
Não analise
ls
; use globs em vez disso. Na verdade, você já está usando globs, apenas envolvê-losls
, o que é inútil. Você só precisanullglob
ativar para quando não há correspondências.Evitar também
cd
simplifica as coisas.Resultado:
Eu adicionei
B/child-3-something
para testar o requisito secundário. Isso cria a estrutura de diretórios para teste:A propósito, o ShellCheck é muito útil para encontrar problemas nos scripts de shell.
fonte
shellcheck
pacote seria o mais seguro]ShellCheck
. Adorei a parte em que ela não apenas informa seus erros, mas também dá sugestões! @ Xen2050, sobre a parte de upload, eu acabei de instalarshellcheck
usandoapt
e depois desabilitei a rede. Parece estar funcionando sem internet .Chamar
ls
uma pasta inexistente lança a mensagem de erro que você encontrou. A maneira mais fácil é simplesmente ignorar isso, substituindo a linha 5 em seu script com este:new_dirs=(`ls -1d $f* 2> /dev/null`);
.fonte
t=(`echo ok; echo err 1>&2`)
$ t (ou${t[@]}
) contém apenas ok, o erro é visto no terminal, mas não é salvo de qualquer maneira. Ou há algo engraçado no meu teste?