Jak przenieść tylko pliki z bieżącego folderu do podfolderu?

9

Nie muszę przenosić folderów, tylko pliki.

Próbowałem, mv *ale to polecenie przenosi również foldery.

Archit
źródło

Odpowiedzi:

13

Jeśli chcesz przenieść wszystko oprócz katalogów z $SOURCE_DIRdo $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
    • Możesz także użyć, -type fjeś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)
Frxstrem
źródło
2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +byłoby bezpieczniejsze (w przypadku $TARGET_DIRbraku katalogu lub dopasowania zaczyna się od -) i bardziej wydajne (ponieważ nie spawnuje nowego podprocesu dla każdego dopasowanego pliku).
David Foerster,
@DavidFoerster Dzięki, zaktualizowano (również dziś dowiedziałem się czegoś nowego!)
Frxstrem
5

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 mvje cp.

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

jeśli to wyjaśnię, find . -type foznacza wybranie wszystkich plików i -exec mv {} $TARGET \;wykonanie mvpolecenia dla wszystkich wybranych pozycji.


Poprzednia odpowiedź zawiera błąd. Dotyczy to również mvwszystkich plików w podkatalogach. Szybka poprawka jest używana -maxdepth 1. Wtedy nie rekurencyjnie zapisuje mvpliki w podkatalogach. Poniżej jest poprawny ..

find . -maxdepth 1 -type f -exec mv {} $TARGET \;
Emalsha Rasad
źródło
Nie sądzę, żeby pytający tego chciał! Przenosi także wszystkie pliki z dowolnych podkatalogów do tego samego katalogu docelowego. -type fNie przeszkadza rekursji.
Martin Thornton
@MartinThornton dziękuję za twoją sugestię ..
Zmienię
3

Podejście do Pythona

Jeśli chodzi o pliki rekurencyjne, findjest to najlepsza droga. W tym konkretnym przypadku nie jest to konieczne, ale można go używać z -maxdepth 1innymi 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

Jak to działa:

  • 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 flutworzeniu 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
Sergiy Kolodyazhnyy
źródło
Oto inne podejście do Pythona
jfs
3

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.

JoL
źródło
1
Jak zauważył David Forester w mojej odpowiedzi, 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!
Frxstrem,
2

Aby przenieść wszystko oprócz katalogów z source-dirkatalogu do destination-dirkatalogu, 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))

Zobacz Uruchamianie pliku Python w terminalu .

jfs
źródło
@SergiyKolodyazhnyy Nie widzę takiego wymogu w Pep-8 i (zgodnie z tamtym przykładem) jest w rzeczywistości dokładnie odwrotnie: import mypackageprzedfrom mypackage import ...
jfs
@SergiyKolodyazhnyy nie myli specjalnego from __future__importu i zwykłego from pathlibimportu.
jfs
Tak, wygląda na to, że źle odczytałem tę część. Nie, masz rację, import modulepowinien być pierwszy (który dotyczy biblioteki i importu stron trzecich) from module import objectpowinien być ostatni (specyficzny dla lokalnej / biblioteki)
Sergiy Kolodyazhnyy
0

Skorzystałbym

mv *.*

będzie to działać, dopóki twoje foldery nie będą miały rozszerzeń.


źródło