Comment déplacer uniquement les fichiers du dossier actuel vers un sous-dossier?

9

Je n'ai pas à déplacer les dossiers, seulement les fichiers.

J'ai essayé mv *mais cette commande déplace également les dossiers.

Archit
la source

Réponses:

13

Si vous souhaitez tout déplacer sauf les répertoires de $SOURCE_DIRà $TARGET_DIR, vous pouvez utiliser cette commande:

find "$SOURCE_DIR" -maxdepth 1 -not -type d -exec mv -t "$TARGET_DIR" -- '{}' +

Expliqué en détail:

  • find: La recherche de recherche de fichiers dans un répertoire
  • $SOURCE_DIR: Le répertoire dans lequel effectuer la recherche
  • -maxdepth 1: Ne regardez pas à l'intérieur des sous-répertoires
  • -not -type d: Ignorer les répertoires
    • Vous pouvez également utiliser -type fsi vous souhaitez uniquement copier des choses qui sont strictement des fichiers, mais je préfère ce qui précède car il capture également tout ce qui n'est ni un fichier ni un répertoire (en particulier les liens symboliques)
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Exécutez la commande mv -t "$TARGET_DIR" -- FILES...où se FILES...trouvent tous les fichiers correspondants (merci @DavidFoerster)
Frxstrem
la source
2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +serait plus sûr (dans le cas où il $TARGET_DIRn'y a pas de répertoire ou la correspondance commence par -) et plus efficace (car il ne génère pas de nouveau sous-processus pour chaque fichier correspondant).
David Foerster
@DavidFoerster Merci, mis à jour (a également appris quelque chose de nouveau aujourd'hui!)
Frxstrem
5

Je pense que vous voulez uniquement mv vos fichiers. Tout d'abord, allez dans votre répertoire et utilisez cette commande, remplacez $ TARGET par le chemin de votre répertoire cible. Si vous souhaitez copier vos fichiers, remplacez mvpar cp.

find . -type f -exec mv {} $TARGET \;

si j'explique cela, find . -type fsignifie sélectionner tous les fichiers et -exec mv {} $TARGET \;signifie exécuter la mvcommande pour tous les éléments sélectionnés.


La réponse précédente a une erreur .. il contient également mvtous les fichiers dans les sous-répertoires. La solution rapide est l'utilisation -maxdepth 1. Ensuite, il ne récursive pas les mvfichiers dans les sous-répertoires. Ci-dessous est le bon ..

find . -maxdepth 1 -type f -exec mv {} $TARGET \;
Emalsha Rasad
la source
Je ne pense pas que le questionneur le veuille! Il déplacerait également tous les fichiers de tous les sous-répertoires dans ce même répertoire cible. Le -type fn'empêche pas la récursivité.
Martin Thornton du
@MartinThornton merci pour votre suggestion .. je vais modifier ma réponse ...
Emalsha Rasad
3

Approche Python

Lorsque vous traitez des fichiers de manière récursive, findc'est la voie à suivre. Dans ce cas particulier, ce n'est pas nécessaire, mais peut être utilisé avec -maxdepth 1comme d'autres réponses le montrent.

Une simple commande python peut également le faire. Voici un exemple:

$ tree
.
├── a_directory
└── a_file

$ python -c "import os,shutil;fl=[f for f in os.listdir('.') if os.path.isfile(f)];                                      
> map(lambda x:shutil.move(x,'./a_directory'),fl)"

$ tree
.
└── a_directory
    └── a_file

1 directory, 1 file

Comment cela fonctionne:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)]itère tous les éléments os.listdir('.')trouvés et nous testons si l'élément est un fichier utilisant la os.path.isfile()fonction.

  • Une fois flla liste des fichiers construite, nous utilisons la map()fonction. Cette fonction prend deux arguments - une fonction et une liste d'éléments; il exécutera la fonction que nous lui avons donnée pour chaque fichier d'une liste. Ainsi, nous avons ici lambda x:shutil.move(x,'./a_directory')une fonction anonyme qui déplace un fichier donné vers un répertoire donné, puis nous avons la fl- la liste des fichiers que nous avons créés.

Pour plus de lisibilité et d'utilisation générale, nous pourrions également réécrire ceci en un script python général, qui prend deux arguments - le répertoire source et le sous-répertoire de destination.

#!/usr/bin/env python3
from os import listdir
from os.path import isfile,realpath
from os.path import join as joinpath
from shutil import move
from sys import argv

# this is script's full path
script=realpath(__file__)
# get all items in a given directory as list of full paths
fl=[ joinpath(argv[1],f) for f in listdir(argv[1]) ] 
# filter out script itself ( just in case) and directories
fl_filtered = [ f for f in fl if isfile(f) and not script == realpath(f) ]
# Uncomment this in case you want to see the list of files to be moved
# print(fl_filtered)
# move the list of files to the given destination
for i in fl_filtered:
     move(i,argv[2])

Et l'utilisation est comme ça:

$ tree
.
├── a_directory
├── a_file
└── files2subdir.py

1 directory, 2 files

# Notice: the script produces no output unless you uncomment print statement
$ ./files2subdir.py "." "./a_directory"                                                                                  

$ tree
.
├── a_directory
│   └── a_file
└── files2subdir.py
Sergiy Kolodyazhnyy
la source
Voici une autre approche Python
jfs
3

Si vous utilisez zsh au lieu de bash, vous pouvez le faire:

mv "$SOURCE"/*(.) "$TARGET"

Le (.)à la fin est appelé un qualificatif glob; l' .intérieur signifie spécifiquement de ne faire correspondre que les fichiers normaux.

Faire un mv *(.) "$target"est rapide et pratique. Cependant, si vous faites cela dans le cadre d'un script, vous voudrez peut-être envisager d'écrire quelque chose comme ce que Frxstrem et David Forester ont suggéré mv -t "$target" -- *(.), pour mieux gérer les cas d'angle qui pourraient survenir dans l'utilisation d'autres personnes.

JoL
la source
1
Comme l'a souligné David Forester dans ma réponse, ce mv -t "$TARGET" -- "$SOURCE"/*(.)serait plus sûr (au cas où "$TARGET"commence par -ou n'est pas un répertoire). J'aime bien la solution zsh!
Frxstrem
2

Pour déplacer tout sauf les répertoires d'un source-dirrépertoire à l'autre destination-dir, en Python:

#!/usr/bin/env python3
"""Usage: mv-files <source-dir> <destination-dir>"""
import shutil
import sys
from pathlib import Path

if len(sys.argv) != 3:
    sys.exit(__doc__)  # print usage & exit 1
src_dir, dest_dir = map(Path, sys.argv[1:])
for path in src_dir.iterdir():
    if not path.is_dir():
        shutil.move(str(path), str(dest_dir / path.name))

Voir Exécution d'un fichier Python dans le terminal .

jfs
la source
@SergiyKolodyazhnyy Je ne vois pas une telle exigence dans pep-8 et (selon l'exemple là-bas) c'est en fait exactement le contraire: import mypackageavantfrom mypackage import ...
jfs
@SergiyKolodyazhnyy ne confond pas les from __future__importations spéciales et les from pathlibimportations ordinaires .
jfs
Oui, on dirait que j'ai mal lu cette partie. Non, vous avez raison, import moduledevrait être le premier (qui est les importations de bibliothèques et de tiers) from module import objectdevrait être le dernier (local / spécifique à la bibliothèque)
Sergiy Kolodyazhnyy
0

J'utiliserais

mv *.*

cela fonctionnera tant que vos dossiers n'auront pas d'extensions.


la source