![Identifique nomes de subdiretórios comuns entre dois diretórios diferentes e exclua-os](https://rvso.com/image/97237/Identifique%20nomes%20de%20subdiret%C3%B3rios%20comuns%20entre%20dois%20diret%C3%B3rios%20diferentes%20e%20exclua-os.png)
Eu tenho dois diretórios dir1
e dir2
centenas de subdiretórios em depth 1
. Eu só preciso de informações sobre os nomes dos subdiretórios que são comuns entre dir1
e dir2
excluí-los sistematicamente de dir2
. Não preciso comparar arquivos ou conteúdo de arquivos. Atuando
diff -qr dir_one dir_two | sort
também produz os nomes dos arquivos, nos quais não estou interessado no momento.
Responder1
Para o seu caso de uso, você pode evitaridentificaros diretórios comuns porque rm -rf
simplesmente ignora os não existentes.
Então bastafind
todosdiretórios dir1
e exclua-os de dir2
:
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --
Algumas explicações. Por padrão, find
todos os diretórios seriam impressos com o caminho completo, que é dir1
. Portanto, estamos usando -printf
para imprimir apenas o nome do arquivo sem os diretórios iniciais (%f) mais o outro caminho "dir2" onde queremos excluir. Além disso, terminamos a string com byte nulo '\0' em vez de nova linha para usar xarg
a opção -0
que torna tudo isso seguro em relação a nomes de arquivos com espaços. Em seguida, xargs
lerá stdin e executará o rm
comando adicionando todas as strings como argumentos.
Observe que antes de excluí-los, você pode testar sua linha de comando adicionando echo
apenas para imprimir os rm
comandos:
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --
Para apenaslistaos diretórios comuns que você poderia usar ls
em vez de rm
(adicionando 2>/dev/null para ignorar os não existentes):
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null
Responder2
comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )
com quebras de linha para facilitar a leitura:
comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
<( cd dir2 && find -maxdepth 1 -type d | sort ) \
| ( cd dir2 && xargs rm -rf )
explicação
find -maxdepth 1 -type d
liste apenas diretórios sem subdiretórios.
cd dir1 && find -maxdepth 1 -type d | sort
primeiro mude para o diretório e depois liste os diretórios.
<( ... )
comm -1 -3 <( ... ) <( ... )
pegue a primeira entrada e a segunda entrada e imprima linhas exclusivas para a segunda entrada. na verdade, isso imprimirá diretórios que estão dentro, dir2
mas não dentro dir1
.
... | ( cd dir2 && xargs rm -rf )
altere o diretório de trabalho para dir2
executar rm -rf
com a saída do comando anterior como argumentos. na verdade, isso excluirá os diretórios que estão em, dir2
mas não em dir1
.
teste primeiro removendo o tubo xargs
e inspecionando a saída.
Responder3
find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c | egrep -v '^ 1 ' | while read n de ; do echo rm -rfv dir2/$de ; done
remova o eco quando correto.