Identifique nomes de subdiretórios comuns entre dois diretórios diferentes e exclua-os

Identifique nomes de subdiretórios comuns entre dois diretórios diferentes e exclua-os

Eu tenho dois diretórios dir1e dir2centenas de subdiretórios em depth 1. Eu só preciso de informações sobre os nomes dos subdiretórios que são comuns entre dir1e dir2excluí-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 -rfsimplesmente ignora os não existentes.

Então bastafind todosdiretórios dir1e 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, findtodos os diretórios seriam impressos com o caminho completo, que é dir1. Portanto, estamos usando -printfpara 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 xarga opção -0que torna tudo isso seguro em relação a nomes de arquivos com espaços. Em seguida, xargslerá stdin e executará o rmcomando adicionando todas as strings como argumentos.

Observe que antes de excluí-los, você pode testar sua linha de comando adicionando echoapenas para imprimir os rmcomandos:

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 lsem 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.

<( ... )

substituição de processo.

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, dir2mas não dentro dir1.

... | ( cd dir2 && xargs rm -rf )

altere o diretório de trabalho para dir2executar rm -rfcom a saída do comando anterior como argumentos. na verdade, isso excluirá os diretórios que estão em, dir2mas não em dir1.

teste primeiro removendo o tubo xargse 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.

informação relacionada