Como mover arquivos em massa um diretório para cima

3

Eu tenho cerca de 200 diretórios em / home /. O problema é que todos eles existem desta maneira:

/ home / {user} / homedir /

Embora deva ser apenas:

/ home / {user} /

Com que comando posso mover todo o conteúdo de um diretório para cada usuário em massa?

Obrigado pela ajuda.

    
por Sander 05.07.2012 / 20:18

6 respostas

5

Isso pode ser diferente dependendo do seu shell, mas assumindo o bash:

for a in $(find /home -maxdepth 1 -type d); do mv $a/homedir/* $a/; rmdir $a/homedir; done

Execute o comando find separadamente para verificar se a lista é a esperada antes de executar o comando completo e remova a parte rmdir se quiser manter o homedir vazio em cada pasta.

    
por 05.07.2012 / 20:38
3

A menos que você exceda o tamanho da linha de comando com os globs mv /home/*/* /home deve funcionar. Observe que, se você tiver arquivos em /home/user , eles também serão movidos para /home .

    
por 05.07.2012 / 20:48
2

Mova o conteúdo homedir para um diretório:

cd /home
for i in */homedir; do /bin/mv $i/* $i/.. && /bin/rmdir $i; done
    
por 05.07.2012 / 22:05
2

Aqui está um script mais paranoico que evita todos os nomes de usuários (usa "@@@" para o diretório tmp), preserva os arquivos de pontos que o "mv $ a / homedir / *" descarta, pára se o @@@ dir isn ' t consistente e não deve ter um problema de comprimento de comando. A fraqueza restante é nomes de usuários patológicos.

cd /home
ls -1 | while read user ; do   # allow many user dirs without imploding
    [ -d @@@ ] && { echo tmp already present, aborting 1>&2 ; exit 1 ; }
    mv $user @@@
    mv @@@/homedir $user
    rmdir @@@ || { echo tmp dir for $user not empty, aborting 1>&2 ; exit 2 ; }
done

A abordagem find () é uma boa escolha se todo o comando por diretório estiver enterrado no -exec, como em:

cd /home && find -name . -o -type d -prune -print \
     -exec mv '{}' @@@ ';' \
     -exec mv @@@/homedir '{}' ';' \
     -exec rmdir @@@ ';'

Tentar algo como "for f in $(find ....)" é frágil, já que os shells desejarão expandir toda a linha de comando primeiro. As descobertas mostradas aqui dependem de {} serem expandidas por find até mesmo dentro de strings, o que não tenho certeza se todas encontram suporte.

ou até mesmo

cd /home && find -name . -o -type d -prune -print -exec \
    sh -c 'mv {} @@@ && mv @@@/homedir {} && rmdir @@@' ';'

Teste:

mkdir -p {fred,jan,alice}/homedir
touch {fred,jan,alice}/homedir/.dotstuff
touch {fred,jan,alice}/homedir/stuff

O deixa rasgar (menos o "cd / home") e veja como isto faz. Tudo parece funcionar bem aqui.

    
por 07.07.2012 / 12:06
1

A solução da SmallClanger pode ser alterada para que os espaços em branco não sejam um problema. O truque é alterar o separador de campo interno do Bash, que é um IFS de callend variável e geralmente contém um espaço em branco e uma nova linha, para apenas conter uma nova linha. Tais como:

IFS=$'\n'

Isso mudaria o IFS para um caractere de nova linha para o seu shell atual.

Depois disso, você pode executar o comando do SmallClanger, ou algo parecido:

for item in $(find ./homedir -mindepth 1 -maxdepth 1 -type d); do
echo " --> \"$item\"" >&2
mv "$item" .
done

Isto assume que o seu diretório de trabalho é "/ home / {user}".

Você pode omitir a linha "mv" quando tentar pela primeira vez ver o que $ item contém. Se parece bom, você o executa com "mv". Não esqueça as aspas duplas em torno de "$ item".

Dessa forma, você só terá problemas se algum dos seus caminhos de arquivo ou pasta contiver novas linhas, o que considero ser muito mais incomum do que elas contendo espaços em branco.

Algumas informações sobre o separador de campo interno: Bash: variáveis internas

Eu também acho que você pode fazer o programa "find" mostrar seus resultados separados por NULs. Se for possível configurar o IFS para NUL, você deve estar no lado seguro para quase tudo, pois normalmente o NUL não é um ponto de código permitido para arquivos / diretórios na maioria dos sistemas de arquivos. Eu nunca tentei isso sozinho, no entanto.

    
por 07.07.2012 / 18:47
0

Eu seria simples

cd /home/user/
mv homedir/* .
    
por 07.07.2012 / 16:58

Tags