Yalnızca geçerli klasördeki dosyalar bir alt klasöre nasıl taşınır?


9

Klasörleri taşımak zorunda değilim, sadece dosyaları.

Denedim mv *ama bu komut klasörleri de taşır.

Yanıtlar:


13

Eğer gelen dizinleri hariç her şeyi taşımak isterseniz $SOURCE_DIRiçin $TARGET_DIR, bu komutu kullanabilirsiniz:

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

Detaylı olarak açıklanmıştır:

  • find: Bir dizindeki dosyaları bulma bulma
  • $SOURCE_DIR: Aranacak dizin
  • -maxdepth 1: Alt dizinlerin içine bakma
  • -not -type d: Dizinleri yoksay
    • -type fSadece kesinlikle dosya olan şeyleri kopyalamak istiyorsanız da kullanabilirsiniz , ancak yukarıdakileri tercih ederim, çünkü ne bir dosya ne de bir dizin olan her şeyi yakalar (özellikle sembolik bağlantılar)
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Eşleşen tüm dosyaların mv -t "$TARGET_DIR" -- FILES...olduğu komutu çalıştırın FILES...(teşekkürler @DavidFoerster)

2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +daha güvenli ( $TARGET_DIRherhangi bir dizin yoksa veya eşleşme ile başlarsa -) ve daha verimli olur (çünkü eşleşen her dosya için yeni bir alt işlem oluşturmaz).
David Foerster

@DavidFoerster Teşekkürler, güncellendi (bugün de yeni bir şey öğrendim!)
Frxstrem

5

İlk önce dizininize gidin ve bu komutu kullanın, $ TARGET yerine hedef dizin yolunuzu değiştirin. Kopyalamak istediğiniz takdirde dosyalarınızı değiştirin mvile cp.

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

Bunu açıklarsam, find . -type ftüm dosyaları seçmek ve seçilen tüm öğelere komut -exec mv {} $TARGET \;yürütmek anlamına gelir mv.


Önceki cevap bir hata var .. mvalt dizinler içindeki tüm dosyaları da. Hızlı düzeltme kullanmaktır -maxdepth 1. Sonra mvalt dizinler içinde özyinelemeli dosyaları değil . Aşağıda doğru olanı ..

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

Soru soranın bunu istediğini sanmıyorum! Ayrıca, herhangi bir alt dizindeki tüm dosyaları aynı hedef dizine taşır. -type fÖzyinelemeyi engellemez.
Martin Thornton

@MartinThornton öneriniz için teşekkür ederim .. Cevabımı düzenleyeceğim ...
Emalsha Rasad

3

Python yaklaşımı

Dosyalarla özyineli olarak uğraşırken find, gitmenin yolu budur. Bu özel durumda gerekli değildir, ancak -maxdepth 1diğer cevapların gösterdiği gibi kullanılabilir .

Basit python komutu da bunu yapabilir. İşte bir örnek:

$ 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

Bu nasıl çalışır:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)]bulan tüm öğeler üzerinde tekrarlanır os.listdir('.')ve öğenin os.path.isfile()işlevi kullanan bir dosya olup olmadığını test ederiz .

  • flDosya listesi oluşturulduktan sonra map()işlevi kullanırız . Bu işlev iki argüman alır - bir işlev ve bir öğe listesi; bir listedeki her dosya başına verdiğimiz işlevi yerine getirir. Böylece burada lambda x:shutil.move(x,'./a_directory')belirli bir dizine verilen bir dosyayı taşıyacağımız anonim bir işlevimiz var ve sonra fl- oluşturduğumuz dosyaların listesine sahibiz.

Okunabilirlik ve genel kullanım için, bunu iki argüman alan genel bir python betiği olarak yeniden yazabiliriz - kaynak dizin ve hedef alt dizin.

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

Ve kullanımı şöyle:

$ 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

İşte başka bir Python yaklaşımı
jfs

3

Eğer bash yerine zsh kullanıyorsanız, bunu yapabilirsiniz:

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

(.)Sonunda topak eleme olarak adlandırılır; .içeride özellikle sadece normal dosyaları maç için anlamına gelir.

A yapmak mv *(.) "$target"hızlı ve pratiktir. Bununla birlikte, bunu bir komut dosyasının parçası olarak yapıyorsanız, bunun yerine Frxstrem ve David Forester'ın önerdiği gibi bir şey yazmayı düşünebilirsiniz mv -t "$target" -- *(.), başkalarının kullanımında ortaya çıkabilecek köşe vakalarını daha iyi ele almak için.


1
David Forester'ın cevabım üzerine işaret ettiği gibi, mv -t "$TARGET" -- "$SOURCE"/*(.)daha güvenli olurdu ( bir dizinle "$TARGET"başlıyorsa -veya bir dizin değilse). Yine de zsh çözümünü seviyorum!
Frxstrem

2

Dizinler dışındaki her şeyi Python'da dizinden source-dirdizine taşımak için destination-dir:

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

Bkz . Terminalde Python Dosyasını Çalıştırma .


@SergiyKolodyazhnyy Pep-8'de böyle bir gereklilik görmüyorum ve (oradaki örneğe göre) aslında tam tersi: import mypackageöncefrom mypackage import ...
jfs

@SergiyKolodyazhnyy özel from __future__ithalat ve normal from pathlibithalat karıştırmayın .
jfs

Evet, görünüşe göre o kısmı yanlış okudum. Hayır, haklısın, import moduleilk olmalı (bu kütüphane ve üçüncü taraf ithalatı) from module import objectson olmalı (yerel / kütüphaneye özgü)
Sergiy Kolodyazhnyy

0

Kullanırdım

mv *.*

klasörleriniz uzantı içermediği sürece bu çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.