Come spostare solo i file nella cartella corrente in una sottocartella?


9

Non devo spostare le cartelle, solo i file.

Ho provato mv *ma questo comando sposta anche le cartelle.

Risposte:


13

Se vuoi spostare tutto tranne le directory da $SOURCE_DIRa $TARGET_DIR, puoi usare questo comando:

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

Spiegato in dettaglio:

  • find: Trova la ricerca di file in una directory
  • $SOURCE_DIR: La directory in cui cercare
  • -maxdepth 1: Non guardare all'interno delle sottodirectory
  • -not -type d: Ignora le directory
    • Puoi anche usarlo -type fse vuoi solo copiare cose che sono rigorosamente file, ma preferisco quanto sopra perché cattura anche tutto ciò che non è né un file né una directory (in particolare i collegamenti simbolici)
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Esegui il comando mv -t "$TARGET_DIR" -- FILES...dove FILES...sono tutti i file corrispondenti (grazie @DavidFoerster)

2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +sarebbe più sicuro (nel caso in cui $TARGET_DIRnon ci sia una directory o la partita inizi con -) e più efficiente (perché non genera un nuovo processo secondario per ogni file corrispondente).
David Foerster,

@DavidFoerster Grazie, aggiornato (ho anche imparato qualcosa di nuovo oggi!)
Frxstrem,

5

Penso che tu voglia mv solo i tuoi file. Prima vai nella tua directory e usa questo comando, sostituisci $ TARGET con il tuo percorso di directory di destinazione. Se si desidera copiare i file, sostituirli mvcon cp.

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

se spiego questo, find . -type fsignifica selezionare tutti i file e -exec mv {} $TARGET \;significa eseguire il mvcomando su tutti gli elementi selezionati.


La risposta precedente ha un errore .. anche mvtutti i file all'interno delle sottodirectory. La soluzione rapida è usare -maxdepth 1. Quindi non mvfile ricorsivamente all'interno di sottodirectory. Di seguito è quello corretto ..

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

Non penso che l'interrogante lo voglia! Sposta anche tutti i file in qualsiasi sottodirectory nella stessa directory di destinazione. Il -type fnon impedisce la ricorsione.
Martin Thornton,

@MartinThornton grazie per il tuo suggerimento ..
Modificherò la

3

Approccio Python

Quando si tratta di file in modo ricorsivo, findè la strada da percorrere. In questo caso particolare non è necessario, ma può essere utilizzato -maxdepth 1come mostrano altre risposte.

Anche il semplice comando python può farlo. Ecco un esempio:

$ 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

Come funziona:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)]scorre su tutti gli elementi che os.listdir('.')trova e testiamo se l'elemento è un file usando la os.path.isfile()funzione.

  • Una volta flcreato l'elenco dei file, usiamo la map()funzione. Questa funzione accetta due argomenti: una funzione e un elenco di elementi; eseguirà la funzione che gli abbiamo dato per ogni file in un elenco. Quindi qui abbiamo una lambda x:shutil.move(x,'./a_directory')funzione anonima che sposta un determinato file in una determinata directory, e quindi abbiamo la fl- la lista dei file che abbiamo creato.

Per leggibilità e uso generale, potremmo anche riscriverlo come uno script python generale, che accetta due argomenti: directory sorgente e sottodirectory destinazione.

#!/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])

E l'uso è così:

$ 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

Ecco un altro approccio Python
jfs

3

Se stai usando zsh invece di bash, puoi farlo:

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

Alla (.)fine si chiama un qualificatore glob; l' .interno significa specificamente abbinare solo i file normali.

Fare un mv *(.) "$target"è rapido e pratico. Tuttavia, se lo stai facendo come parte di una sceneggiatura, potresti prendere in considerazione l'idea di scrivere qualcosa di simile a quello che Frxstrem e David Forester hanno suggerito mv -t "$target" -- *(.), per gestire meglio i casi angolari che potrebbero sorgere nell'uso di altre persone.


1
Come ha sottolineato David Forester nella mia risposta, mv -t "$TARGET" -- "$SOURCE"/*(.)sarebbe più sicuro (nel caso in cui "$TARGET"inizi con una -o non sia una directory). Mi piace la soluzione zsh però!
Frxstrem,

2

Per spostare tutto tranne le directory da source-dirdirectory a destination-dirdirectory, in 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))

Vedi Esecuzione di Python File nel Terminale .


@SergiyKolodyazhnyy Non vedo questo requisito in pep-8 e (secondo l'esempio lì) è in realtà l'esatto contrario: import mypackageprimafrom mypackage import ...
jfs

@SergiyKolodyazhnyy non confonde le from __future__importazioni speciali e le from pathlibimportazioni ordinarie .
jfs

Sì, sembra che ho letto male quella parte. No, hai ragione, import moduledovrebbe essere il primo (che è l'importazione di librerie e di terze parti) from module import objectdovrebbe essere l'ultimo (locale / specifico della biblioteca)
Sergiy Kolodyazhnyy,

0

Vorrei usare

mv *.*

questo funzionerà fintanto che le tue cartelle non hanno estensioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.