Làm thế nào để di chuyển Chỉ các tập tin trong thư mục hiện tại sang một thư mục phụ?


9

Tôi không phải di chuyển các thư mục, chỉ các tập tin.

Tôi đã thử mv *nhưng lệnh này cũng di chuyển các thư mục.

Câu trả lời:


13

Nếu bạn muốn di chuyển mọi thứ trừ các thư mục từ $SOURCE_DIRđến $TARGET_DIR, bạn có thể sử dụng lệnh này:

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

Giải thích chi tiết:

  • find: Tìm kiếm các tập tin trong một thư mục
  • $SOURCE_DIR: Thư mục để tìm kiếm trong
  • -maxdepth 1: Đừng nhìn vào các thư mục con
  • -not -type d: Bỏ qua thư mục
    • Bạn cũng có thể sử dụng -type fnếu bạn chỉ muốn sao chép những thứ thuộc tệp nghiêm ngặt, nhưng tôi thích ở trên vì nó cũng nắm bắt mọi thứ không phải là tệp hay thư mục (đặc biệt là các liên kết tượng trưng)
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Chạy lệnh mv -t "$TARGET_DIR" -- FILES...trong đó FILES...có tất cả các tệp phù hợp (cảm ơn @DavidFoerster)

2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +sẽ an toàn hơn (trong trường hợp $TARGET_DIRkhông có thư mục hoặc trận đấu bắt đầu -) và hiệu quả hơn (vì nó không sinh ra một quy trình phụ mới cho mỗi tệp phù hợp).
David Foerster

@DavidFoerster Cảm ơn, đã cập nhật (cũng đã học được điều gì đó mới hôm nay!)
Frxstrem

5

Tôi nghĩ rằng bạn chỉ muốn mv các tệp của mình. Trước tiên, hãy vào thư mục của bạn và sử dụng lệnh này, thay thế $ TARGET bằng đường dẫn thư mục đích của bạn. Nếu bạn muốn sao chép các tập tin của bạn thay thế mvbằng cp.

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

nếu tôi giải thích điều này, find . -type fcó nghĩa là chọn tất cả các tệp và -exec mv {} $TARGET \;có nghĩa là thực thi mvlệnh cho tất cả các mục đã chọn.


Câu trả lời trước có lỗi .. mvtất cả các tệp trong thư mục con cũng có. Cách khắc phục nhanh là sử dụng -maxdepth 1. Sau đó, nó không đệ quy mvcác tập tin trong các thư mục phụ. Dưới đây là một trong những chính xác ..

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

Tôi không nghĩ người hỏi muốn điều này! Nó cũng sẽ di chuyển tất cả các tệp trong bất kỳ thư mục con nào vào cùng thư mục đích đó. Các -type fkhông ngăn cản đệ quy.
Martin Thornton

@MartinThornton cảm ơn bạn đã gợi ý .. tôi sẽ chỉnh sửa câu trả lời của mình ...
Emalsha Rasad

3

Cách tiếp cận Python

Khi xử lý các tệp đệ quy, findlà cách để đi. Trong trường hợp cụ thể này, nó không cần thiết, nhưng có thể được sử dụng -maxdepth 1như các câu trả lời khác cho thấy.

Lệnh python đơn giản cũng có thể làm điều đó. Đây là một ví dụ:

$ 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

Cách thức hoạt động:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)]lặp đi lặp lại trên tất cả các mục os.listdir('.')tìm thấy và chúng tôi kiểm tra xem mục đó có phải là tệp sử dụng os.path.isfile()hàm hay không.

  • Khi fldanh sách tập tin được xây dựng, chúng tôi sử dụng map()chức năng. Hàm này có hai đối số - một hàm và một danh sách các mục; nó sẽ thực hiện chức năng mà chúng tôi đã cung cấp cho mỗi tệp trong một danh sách. Vì vậy, ở đây chúng ta có lambda x:shutil.move(x,'./a_directory')chức năng ẩn danh sẽ di chuyển một tệp đã cho vào một thư mục nhất định và sau đó chúng ta có fl- danh sách các tệp mà chúng ta đã tạo.

Để dễ đọc và sử dụng chung, chúng ta cũng có thể viết lại đây là tập lệnh python chung, trong đó có hai đối số - thư mục nguồn và thư mục con đích.

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

Và cách sử dụng là như vậy:

$ 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

Đây là một cách tiếp cận Python
jfs

3

Nếu bạn đang sử dụng zsh thay vì bash, bạn có thể làm điều này:

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

Các (.)cuối cùng được gọi là một vòng loại glob; các .bên đặc biệt có nghĩa là chỉ phù hợp với các file thông thường.

Làm một mv *(.) "$target"là nhanh chóng và thiết thực. Tuy nhiên, nếu bạn đang thực hiện điều này như một phần của kịch bản, bạn có thể muốn xem xét thay vì viết một cái gì đó giống như những gì Frxstrem và David Forester đề xuất mv -t "$target" -- *(.), để xử lý tốt hơn các trường hợp góc có thể phát sinh trong việc sử dụng của người khác.


1
Như David Forester đã chỉ ra câu trả lời của tôi, mv -t "$TARGET" -- "$SOURCE"/*(.)sẽ an toàn hơn (trong trường hợp "$TARGET"bắt đầu bằng một -hoặc không phải là một thư mục). Tôi thích giải pháp zsh!
Frxstrem

2

Để di chuyển mọi thứ trừ thư mục từ source-dirthư mục này sang destination-dirthư mục khác, trong 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))

Xem Chạy tệp Python trong Terminal .


@SergiyKolodyazhnyy Tôi không thấy yêu cầu như vậy trong pep-8 và (theo ví dụ ở đó) nó thực sự hoàn toàn ngược lại: import mypackagetrướcfrom mypackage import ...
jfs

@SergiyKolodyazhnyy đừng nhầm lẫn giữa from __future__hàng nhập khẩu đặc biệt và from pathlibhàng nhập khẩu thông thường .
jfs

Vâng, có vẻ như tôi đã đọc sai phần đó. Không, bạn đúng, import modulenên là người đầu tiên (là thư viện và nhập khẩu của bên thứ ba) from module import objectnên là lần cuối (cụ thể tại địa phương / thư viện)
Sergiy Kolodyazhnyy

0

Tôi sẽ sử dụng

mv *.*

điều này sẽ hoạt động miễn là các thư mục của bạn không có tiện ích mở rộng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.