Mueve todos los archivos que no son un directorio

14

Tengo un directorio que estoy tratando de limpiar que contiene archivos y subdirectorios. Lo que intento hacer es simple: mover todos los archivos a otro directorio, pero dejar todos los subdirectorios como están.

Estoy pensando algo como:

mv [*_but_no_dirs] ./other_directory

Parece que debería haber una manera simple de hacer esto con comodines *y expresiones regulares ...

Alguien tiene ideas?

Questionmark
fuente
1
¿Entonces mover todos los archivos en una subcarpeta, pero ignorar alguno en los subdirectorios?
Wilf
@Wilf: Exactamente.
Questionmark
2
En zsh, podría hacerlo mv **/*(.) ./other_directory; sin embargo , con bash necesitaría recurrir a comandos externos como find.
godlygeek

Respuestas:

12

Regex no está involucrado aquí. Los comodines en bash (como la mayoría de los otros shells) solo coinciden con los archivos según los nombres de los archivos, no según el tipo de archivo u otras características. Hay una manera de hacer coincidir por tipo: agregar /al final del patrón hace que solo coincida con directorios o enlaces simbólicos a directorios. De esta manera, puede mover directorios, luego mover lo que queda y mover directorios hacia atrás, lo cual es engorroso pero funciona.

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

Una forma estándar de hacer coincidir archivos por tipo es llamar find.

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

En zsh, puede usar calificadores globales para unir archivos por tipo. El .calificador coincide con los archivos normales; use ^/para hacer coincidir todos los no directorios, o -^/también para incluir enlaces simbólicos a directorios.

mv -- *(.) other_directory/

En cualquier shell, puedes simplemente hacer un bucle.

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

Podrías usar algo como

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

Primero usamos findpara mirar solo dentro del directorio actual, luego ignoramos los directorios usando ! -type d finalmente ejecutamos shy movemos todo al directorio de destino. Puede intentar {} +al final, que será más rápido.

Valentin Bajrami
fuente
2
Un poco de explicación, por favor ...
Questionmark
1
@Questionmark He actualizado la respuesta y agregué alguna explicación. Además, vale la pena visitar mywiki.wooledge.org/UsingFind
Valentin Bajrami
¿Por qué sugieres en -exec sh -c 'mv "$@" MYDIR' _ {} \;lugar de -exec mv {} MYDIR \;? ¿Solo para obtener algo que se pueda simplificar cambiando el \;a +? Puedes hacerlo con el -exec mv -t MYDIR {} +formulario.
Scott
@ Scott No tenía idea de la -tbandera. También expliqué en la respuesta que +es más rápido pero no todas las findversiones lo admiten. Por lo tanto, el código anterior es bastante compatible con cualquiera findo shell que se utiliza.
Valentin Bajrami
1
@ val0x00ff: "... el código anterior es bastante compatible con cualquiera findo shell que se utiliza". Es cierto, pero también lo es find … -exec mv {} MYDIR \;, y utiliza menos recursos que … -exec sh -c 'mv "$@" MYDIR' _ {} \;.
Scott
0

Es potencialmente un poco peligroso pero

cp * destination/
rm *

Como cp y rm no funcionarán en directorios sin el modificador -r.

Mike
fuente
-1

Sugeriría simplemente hacer mv *.* destination/con el destino / ser la carpeta a la que se está moviendo.

Peter Z
fuente
2
visite: unix.stackexchange.com/help/formatting
Jeff Schaller
2
Los nombres de directorio pueden contener 'punto' y los nombres de archivo pueden excluirlo (y a menudo lo hacen), por *.*lo que moverá algunos directorios y dejará algunos archivos, que no es lo que el autor de la pregunta quería.
dave_thompson_085
Lo siento, pero esto está completamente mal. Simplemente moverá cualquier cosa con un punto en su nombre y no moverá nada sin uno. Los puntos no son exclusivos de los archivos y tampoco son necesarios para los archivos, por lo que esto solo moverá una selección aleatoria de archivos y directorios.
terdon
-2
mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move
sy s
fuente