Odpowiedzi:
Jeśli chcesz przenieść wszystko oprócz katalogów z $SOURCE_DIR
do $TARGET_DIR
, możesz użyć tego polecenia:
find "$SOURCE_DIR" -maxdepth 1 -not -type d -exec mv -t "$TARGET_DIR" -- '{}' +
Szczegółowo wyjaśnione:
find
: Znajdź wyszukiwanie plików w katalogu$SOURCE_DIR
: Katalog do przeszukania-maxdepth 1
: Nie zaglądaj do podkatalogów-not -type d
: Ignoruj katalogi
-type f
jeśli chcesz kopiować tylko pliki, które są ściśle plikami, ale wolę powyższe, ponieważ przechwytuje wszystko, co nie jest ani plikiem, ani katalogiem (w szczególności dowiązaniami symbolicznymi)-exec mv -t "$TARGET_DIR" -- '{}' +
: Uruchom polecenie, w mv -t "$TARGET_DIR" -- FILES...
którym FILES...
znajdują się wszystkie pasujące pliki (dzięki @DavidFoerster)Myślę, że chcesz mv tylko swoje pliki. Najpierw przejdź do katalogu i użyj tego polecenia, zamień $ TARGET na ścieżkę katalogu docelowego. Jeśli chcesz skopiować pliki, zastąp mv
je cp
.
find . -type f -exec mv {} $TARGET \;
jeśli to wyjaśnię, find . -type f
oznacza wybranie wszystkich plików i -exec mv {} $TARGET \;
wykonanie mv
polecenia dla wszystkich wybranych pozycji.
Poprzednia odpowiedź zawiera błąd. Dotyczy to również mv
wszystkich plików w podkatalogach. Szybka poprawka jest używana -maxdepth 1
. Wtedy nie rekurencyjnie zapisuje mv
pliki w podkatalogach. Poniżej jest poprawny ..
find . -maxdepth 1 -type f -exec mv {} $TARGET \;
-type f
Nie przeszkadza rekursji.
Jeśli chodzi o pliki rekurencyjne, find
jest to najlepsza droga. W tym konkretnym przypadku nie jest to konieczne, ale można go używać z -maxdepth 1
innymi odpowiedziami.
Proste polecenie Pythona może to również zrobić. Oto przykład:
$ 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
fl=[f for f in os.listdir('.') if os.path.isfile(f)]
iteruje wszystkie os.listdir('.')
znalezione elementy, a my sprawdzamy, czy dany plik jest plikiem przy użyciu os.path.isfile()
funkcji.
Po fl
utworzeniu listy plików korzystamy z map()
funkcji. Ta funkcja przyjmuje dwa argumenty - funkcję i listę elementów; wykona funkcję, którą mu nadaliśmy dla każdego pliku na liście. Mamy więc tutaj lambda x:shutil.move(x,'./a_directory')
anonimową funkcję, która przeniesie dany plik do danego katalogu, a następnie mamy fl
- listę plików, które zbudowaliśmy.
Aby zapewnić czytelność i ogólne użycie, możemy również przepisać to jako ogólny skrypt Pythona, który przyjmuje dwa argumenty - katalog źródłowy i docelowy podkatalog.
#!/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])
A użycie jest takie:
$ 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
Jeśli używasz zsh zamiast bash, możesz to zrobić:
mv "$SOURCE"/*(.) "$TARGET"
Na (.)
końcu nazywa się globalny kwalifikator; .
wewnątrz oznacza konkretnie tylko dopasować zwykłe pliki.
Robienie mv *(.) "$target"
jest szybkie i praktyczne. Jeśli jednak robisz to jako część skryptu, możesz zamiast tego rozważyć napisanie czegoś takiego, jak sugerowali Frxstrem i David Forester mv -t "$target" -- *(.)
, aby lepiej obsługiwać przypadki narożne, które mogą powstać w przypadku korzystania z innych osób.
mv -t "$TARGET" -- "$SOURCE"/*(.)
byłoby bezpieczniej (w przypadku gdy "$TARGET"
zaczyna się -
od katalogu lub nie jest katalogiem). Podoba mi się jednak rozwiązanie zsh!
Aby przenieść wszystko oprócz katalogów z source-dir
katalogu do destination-dir
katalogu, w Pythonie:
#!/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))
import mypackage
przedfrom mypackage import ...
from __future__
importu i zwykłego from pathlib
importu.
import module
powinien być pierwszy (który dotyczy biblioteki i importu stron trzecich) from module import object
powinien być ostatni (specyficzny dla lokalnej / biblioteki)
Skorzystałbym
mv *.*
będzie to działać, dopóki twoje foldery nie będą miały rozszerzeń.
find ... -exec mv -t "$TARGET_DIR" -- '{}' +
byłoby bezpieczniejsze (w przypadku$TARGET_DIR
braku katalogu lub dopasowania zaczyna się od-
) i bardziej wydajne (ponieważ nie spawnuje nowego podprocesu dla każdego dopasowanego pliku).