Fragmento de bash para mover todos los archivos de un directorio a ese directorio

14

Tengo un directorio con muchos archivos y directorios. Para ordenarlo, voy a poner todos esos archivos en un directorio, así que iba a hacer algo como esto:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Sin embargo, obviamente, que no va a funcionar porque entonces se va a tratar de moverse new_directoryen new_directory. ¿Hay alguna forma simple de hacer lo que quiero en una línea sin que tenga que copiar y pegar todos los archivos y directorios en ese directorio?

Rory
fuente
3
funciona, solo imprime un mensaje de error que indica que no puede mover new_directory a sí mismo.
cas

Respuestas:

18

Tu

mv * ./new_directory
comando realmente funcionará; solo imprimirá una advertencia de que no puede mover ese directorio dentro de sí mismo.

mibus
fuente
El "único" problema con esto es que si la expansión total del comando es demasiado larga (es decir, demasiados archivos, nombres demasiado largos), esto ya no funcionará.
Niels Basjes
Como nota al margen, si va a hacer esto con un git mvdebe usar la -kbandera, ya que git fallará de forma predeterminada, no solo escupe una advertencia. Entonces tendrás que hacer git mv -k * ./new_dir.
Yuval A
11

Un forro rápido y sucio.

mv `ls -A | grep -v new_directory` ./new_directory

fuente
1
No funcionará: un ls simple no mostrará archivos de puntos.
wzzrd
Muy buen punto. Arreglado eso con un -a.
2
Entonces, en lugar de intentar mv new_directory para sí mismo (Pregunta original), ahora está tratando de moverse. y .. en new_directory.
Niels Basjes
2
Gracias por los comentarios Niels. Se corrigió con una a superior que elimina la. y el ... de la lista del directorio.
8

Si solo está buscando los archivos (es decir, no directorios), entonces

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

Es la solución más portátil. Para la velocidad, debe mover find y xargs, con -print0 y -0, pero solo si tiene GNU find y xargs.

Cian
fuente
3
Usando un hallazgo de GNU bastante reciente, también podría usar \ + en lugar de \; para disminuir la cantidad de mv que estamos haciendo.
wzzrd
Si tiene GNU find, también puede usar xargs, que hará lo mismo, y le permitirá ejecutar múltiples mvs al mismo tiempo con la bandera -p.
Cian
uso genial de find- aunque definitivamente he estado en sistemas que no tienen uno, lamentablemente :(
warren
De Verdad? find se especifica (afaik) en SUS, por lo que todo debería tenerlo. El único problema es si se trata de GNU find (que tiene muchas buenas opciones interesantes) o find regular.
Cian
6

Las veces que tuve este problema, hice uno de los siguientes:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

o

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

La segunda forma aprovecha los comodines que omiten los nombres de archivo que comienzan con '.'

Kenster
fuente
Olvidé los archivos de puntos salteados con comodines; Gracias por el recordatorio ! :)
aemonge
2

qué pasa:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, no mueva el contenido a un nuevo directorio, pero coloque este directorio dentro de uno nuevo.

Javier
fuente
1

De manera similar a la respuesta de @ Rembrane (aunque no de una sola línea):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Esto debería ser 100% portátil, incluso si findlamentablemente está ausente de su sistema.

madriguera
fuente
find es obligatorio en la especificación de unix único. Como tal, nunca debería estar ausente (no es que no pudieras construir algo sin él. Pero me imagino que requeriría una cantidad horrible de esfuerzo, y ningún sistema de proveedores lo carecerá)
Cian
tal vez es un sysadmin hiper-paranoico que busca findutils o su equivalente? no estoy seguro, pero sé que me he encontrado con boxen que no lo tiene :(
warren
1

Mis sugerencias: como han dicho otros,

mv * ./new_directory

funcionará encontrar IFF la expansión total es lo suficientemente corta.

De lo contrario, puede probar este que escala a un número mucho mayor de archivos:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Explicación

  1. Lista todos los archivos.
  2. Agrupe todos los nombres de archivos en fragmentos de un máximo de 100000 caracteres.
  3. Construya un solo comando mv por fragmento.
Niels Basjes
fuente
se rompe si tienes espacios en los nombres de tus archivos
Cian
Tienes razón. Así que supongo que esto debería aumentarse con los indicadores -print0 y -0 para corregir.
Niels Basjes
He intentado con -print0y -0y todavía se rompe.
Cristian Ciupitu
find: advertencia: ha especificado la opción -maxdepth después de un tipo de argumento sin opción, pero las opciones no son posicionales (-maxdepth afecta las pruebas especificadas antes y las especificadas después). Por favor, especifique las opciones antes de otros argumentos.
Cristian Ciupitu
1

Utilizar:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Desde la xargspágina del manual:

-P max-procs

  Run up to max-procs processes at a time;
Cristian Ciupitu
fuente
-1

Para evitar el mensaje de error y mantenerlo simple:

mv *.* ./new_Folder

hará lo mismo pero evitará el mensaje de error (a menos que tenga puntos en los nombres de sus carpetas, supongo).

usuario157734
fuente