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

3

Eu tenho dois dirs dir1 e dir2 que têm centenas de subdiretórios em depth 1 . Eu só preciso de informações dos nomes de subdiretórios que são comuns entre dir1 e dir2 e sistematicamente excluí-los de dir2 . Não preciso comparar arquivos ou conteúdo de arquivos. Realizando

diff -qr dir_one dir_two | sort

produz os nomes de arquivos também, o que não me interessa no momento.

    
por WanderingMind 25.10.2016 / 16:40

3 respostas

2

Para o seu caso de uso, você pode evitar identificar os diretórios comuns, porque rm -rf apenas ignora os não existentes.

Então, é suficiente para find todos diretórios em dir1 e excluí-los de dir2 :

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f
find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f%pre%" |xargs -0 -r ls -d -- 2>/dev/null
" |xargs -0 echo rm -rf --
" |xargs -0 rm -rf --
" |xargs -0 -r ls -d -- 2>/dev/null
" |xargs -0 echo rm -rf --
" |xargs -0 rm -rf --

Algumas explicações. Por padrão, find imprimiria todos os diretórios com o caminho completo, que é dir1 . Portanto, estamos usando -printf para imprimir apenas o nome do arquivo sem os diretórios principais (% f), além do outro caminho "dir2" onde queremos excluir. Além disso, terminamos a string com byte nulo '\ 0' em vez de nova linha para usar xarg option -0 , o que torna tudo isso seguro em relação a nomes de arquivos com espaços. Então xargs lerá stdin e executará o comando rm adicionando todas as strings como argumentos.

Note que, antes de excluí-los, você pode testar sua linha de comando adicionando echo para imprimir apenas os comandos rm :

%pre%

Para apenas listar os diretórios comuns, você pode usar ls em vez de rm (adicionando 2 > / dev / null para ignorar os não existentes):

%pre%     
por 25.10.2016 / 16:55
1
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 legibilidade:

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

lista somente diretórios sem subdiretórios.

cd dir1 && find -maxdepth 1 -type d | sort

primeiro mude para o diretório e liste os diretórios.

<( ... )

substituição de processos .

comm -1 -3 <( ... ) <( ... )

pegue a primeira entrada e a segunda entrada e as linhas de impressão exclusivas da segunda entrada. Na verdade, isso irá imprimir diretórios que estão em dir2 , mas não em dir1 .

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

altere o diretório de trabalho para dir2 e execute 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 pipe para xargs e inspecionando a saída.

    
por 25.10.2016 / 16:56
-1
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 estiver correto.

    
por 25.10.2016 / 16:57