Como mover todas as pastas irmãs para uma pasta?

6

Peço desculpas por parecer uma pergunta tão idiota, mas não posso me dar ao luxo de estragar tudo.

Eu tenho um monte de pastas assim:

/users/me/foo/oops1

/users/me/foo/oops2

/users/me/foo/oops3

/users/me/foo/oops4

/users/me/foo/bar

Infelizmente, eles não são nomeados uniformemente assim e há centenas de pastas oops.

Eu pretendia copiar todas as pastas oops em bar. Existe uma maneira fácil de mover todas as pastas oops para uma barra que não resulte em algum tipo de problema de movimento recursivo?

Demorou várias horas para copiar os arquivos. Espero que o movimento seja muito mais rápido.

Isto está em um servidor redhat linux pelo caminho. Eu só tenho acesso ssh.

Eu acho que se eu fizer

cd foo
mv * bar

haverá um problema.

    
por jgritty 19.01.2013 / 23:23

5 respostas

3

Infelizmente, a resposta de Matt e A resposta de Nicole apresenta um estilo ruim e será quebrada se qualquer uma das pastas contiver um único caractere de espaço em branco, um caractere globbing (como * ) ou uma nova linha. A execução de for item in $(ls …) é um grande erro que se pode cometer, porque será mais rápido ou mais tarde, e iterar sobre nomes de arquivos, não emiti-los corretamente pode causar todos os tipos de problemas.

Nunca analise a saída de ls .

Há uma ferramenta no Linux para encontrar arquivos que correspondam a determinados critérios e é chamada de find :

find . -mindepth 1 -maxdepth 1 \
-type d ! -regex ".\/bar$" \
-exec mv '{}' ./bar/ \;

Isso moverá todos os diretórios no diretório de trabalho atual que não são chamados bar into ./bar/ . Ele funcionará mesmo que os nomes dos diretórios contenham espaços, caracteres globbing ou newlines.

A expressão regular .\/bar$ corresponderá apenas ao diretório chamado ./bar e será negada por ! .

    
por 20.01.2013 / 11:46
6

O que você está propondo é exatamente correto. mv é inteligente o suficiente e dirá o seguinte:

mv: cannot move 'bar' to a subdirectory of itself, 'bar/bar'

No entanto, todos os seus diretórios do oopsx estarão dentro da barra.

    
por 19.01.2013 / 23:30
3

Sim, você está certo, isso seria um problema porque * também corresponderá a bar ; você não pode entrar no diretório mv .

A maneira mais inteligente é usar a substituição de comandos e um loop para mv apenas as coisas que não são bar . Por exemplo, em bash , você poderia escrever algo assim, mas observe que ele falhará se atingir um nome que contenha um espaço (porque a substituição de comandos divide as coisas em palavras nos espaços).

mv $(for i in *; do if [ $i != "bar" ]; then echo $i; fi; done) bar

Mas, sinceramente, sou preguiçoso. Eu iria mv bar fora do caminho, então mv tudo para ele, então mova-o de volta. Você está apenas movendo links do sistema de arquivos, não o conteúdo do arquivo, por isso é rápido. Isso também tem a vantagem de funcionar se você tiver nomes com espaços.

cd foo
mv bar ../bar.save
mv * ../bar.save
mv ../bar.save bar
    
por 19.01.2013 / 23:35
1

Se você se sentir mais seguro, poderá fazer isso em BASH:

for item in 'ls -d | grep -v "^bar$"'; do mv $item bar; done;
    
por 19.01.2013 / 23:34
-1

cd em foo

mv -t bar oops[[:digit:]]

do mais geral

mv -t bar oops*
    
por 19.01.2013 / 23:32