Mova todos os arquivos que não são um diretório

14

Eu tenho um diretório que estou tentando limpar que contém arquivos e subdiretórios. O que estou tentando fazer é simples: mova todos os arquivos para outro diretório, mas deixe todos os subdiretórios como estão.

Estou pensando em algo como:

mv [*_but_no_dirs] ./other_directory

Parece que deve haver uma maneira simples de fazer isso com caracteres curinga *e regex ...

Alguém tem ideias?

Ponto de interrogação
fonte
1
Então mova todos os arquivos em uma subpasta, mas ignore os subdiretórios?
Wilf 29/07
@ Wilf: Exatamente.
Questionmark
2
No zsh, você pode fazer mv **/*(.) ./other_directory- com o bash, você precisará recorrer a comandos externos como esse find.
21914 godlygeek

Respostas:

12

Regex não está envolvido aqui. Os curingas no bash (como a maioria dos outros shells) correspondem apenas aos arquivos com base nos nomes dos arquivos, não no tipo de arquivo ou em outras características. Há uma maneira de corresponder por tipo: adicionar /no final do padrão faz corresponder apenas diretórios ou links simbólicos aos diretórios. Dessa forma, você pode mover diretórios, depois mover o que resta e mover diretórios de volta - pesado, mas funciona.

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

Uma maneira padrão de corresponder arquivos por tipo é ligar find.

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

No zsh, você pode usar os qualificadores glob para corresponder aos arquivos por tipo. O .qualificador corresponde aos arquivos regulares; use ^/para corresponder a todos os não diretórios ou -^/também para incluir links simbólicos para diretórios.

mv -- *(.) other_directory/

Em qualquer shell, você pode simplesmente fazer um loop.

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done
Gilles 'SO- parar de ser mau'
fonte
8

Você poderia usar algo como

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

Primeiro, usamos findapenas para procurar no diretório atual, depois ignoramos os diretórios usando ! -type d finalmente executamos she movemos tudo para o diretório de destino. Você pode tentar {} +no final o que será mais rápido.

Valentin Bajrami
fonte
2
Um pouco de explicação, por favor ...
Questionmark
1
@Questionmark Atualizei a resposta e adicionei algumas explicações. Além disso, vale a pena visitar mywiki.wooledge.org/UsingFind
Valentin Bajrami
Por que você sugere, em -exec sh -c 'mv "$@" MYDIR' _ {} \;vez de -exec mv {} MYDIR \;? Apenas para obter algo que possa ser simplificado alterando o \;para a +? Você pode fazer isso com o -exec mv -t MYDIR {} +formulário.
297 Scott
@ Scott Eu não tinha ideia da -tbandeira. Expliquei também na resposta que a versão +é mais rápida, mas nem todas as findversões suportam. Portanto, o código acima é praticamente compatível com qualquer findshell ou que é usado.
Valentin Bajrami 29/07
1
@ val0x00ff: “… o código acima é praticamente compatível com qualquer findshell ou que é usado.” É verdade, mas é find … -exec mv {} MYDIR \;, e usa menos recursos que … -exec sh -c 'mv "$@" MYDIR' _ {} \;.
Scott
0

É potencialmente um pouco perigoso, mas

cp * destination/
rm *

Como cp e rm não funcionarão em diretórios sem a opção -r.

miick
fonte
-1

Eu sugeriria simplesmente fazer mv *.* destination/com o destino / ser a pasta para a qual você está se movendo.

Peter Z
fonte
2
confira: unix.stackexchange.com/help/formatting
Jeff Schaller
2
Os nomes de diretório podem conter 'ponto' e os nomes de arquivos podem excluí-lo (e geralmente o fazem), portanto *.*, alguns diretórios são movidos e alguns arquivos são deixados, o que não é o que o solicitante queria.
Dave_thompson_085
Desculpe, mas isso está completamente errado. Simplesmente moverá qualquer coisa com um ponto no nome e não moverá nada sem um. Os pontos não são de forma alguma exclusivos para os arquivos e também não são exigidos pelos arquivos, portanto, isso apenas moverá uma seleção aleatória de arquivos e diretórios.
terdon
-2
mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move
sy s
fonte