Di chuyển tất cả các tệp có phần mở rộng nhất định từ nhiều thư mục con vào một thư mục


43

Tôi có một loạt các tệp .zip trong một số thư mục:

Fol1/Fol2
Fol3
Fol4/Fol5

Làm thế nào tôi có thể di chuyển tất cả chúng vào một thư mục cơ sở chung?


Bạn có muốn giữ cấu trúc thư mục? Bạn muốn di chuyển các thư mục, hoặc chỉ các tập tin zip?
jordanm

Tôi chỉ muốn di chuyển các tập tin zip. Tôi không thực sự quan tâm đến các thư mục - chúng có thể bị bỏ lại một mình hoặc bị xóa.
InquilineKea

Câu trả lời:


55

Chuyển đến thư mục toplevel của cây chứa tệp zip ( cd …), sau đó chạy

mv **/*.zip /path/to/single/target/directory

Điều này làm việc ra khỏi hộp trong zsh. Nếu shell của bạn bị bash, bạn sẽ cần chạy shopt -s globstartrước (bạn có thể và nên đặt lệnh này trong của bạn ~/.bashrc). Nếu vỏ của bạn là ksh, bạn sẽ cần chạy set -o globstartrước (đặt nó vào trong ~/.kshrc).

Ngoài ra, sử dụng find, hoạt động ở mọi nơi không có sự chuẩn bị đặc biệt nhưng phức tạp hơn:

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

Nếu bạn muốn xóa các thư mục trống sau đó, trong zsh:

rmdir **/*(/^Fod)

Trong bash hoặc ksh:

rmdir **/*/

và lặp lại miễn là có thư mục trống để loại bỏ. Ngoài ra, trong bất kỳ vỏ

find . -depth -type d -empty -exec rmdir {} \;

findLệnh đầu tiên ở trên hoạt động trong bash, nhưng phải đổi thành find . -namevv để làm cho nó hoạt động.
JeffThndry

1
@Jeff .là ẩn cho GNU tìm nhưng không phải cho người khác, tôi đã thêm nó một cách rõ ràng.
Gilles 'SO- ngừng trở nên xấu xa'

13

Nếu bạn chỉ muốn di chuyển các .ziptập tin, bạn có thể làm một cái gì đó như

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;

3

Nếu bạn đang sử dụng bash phiên bản 4 trở lên hoặc zsh, bạn cũng có thể sử dụng tính năng đệ quy đệ quy:

mv **/*.zip /path/to/move/zip/files/to

Điều này sẽ di chuyển CHỈ các tệp và không phải đường dẫn tương đối của chúng, vì vậy có thể xảy ra va chạm.


bạn có ý nghĩa gì bởi những con đường tương đối?
Kunok

2

Điều này là an toàn khi di chuyển dữ liệu và không có lỗi, hỗ trợ hầu hết tất cả các bản phân phối bất kể phiên bản nào. Lệnh này sẽ quét các thư mục con và sau đó di chuyển hoặc sao chép vào thư mục đích mới của bạn.

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • Chạy lệnh này tại thư mục chính có chứa các thư mục con với các tệp bạn muốn di chuyển.
  • Nơi bạn có thể thay đổi *.flacthành bất cứ điều gì như *.ziptrong trường hợp của bạn. Hoặc *.docbất kỳ phần mở rộng hoạt động.
  • mvlà lệnh để di chuyển tệp hoặc bạn có thể sử dụng cpđể sao chép dữ liệu thay vì di chuyển.
  • ./flac/là thư mục đích mà tôi muốn di chuyển tất cả các tệp FLAC sang. Bạn cũng có thể cung cấp cho nó một đường dẫn đầy đủ như/home/myid/flac/

Ví dụ đầy đủ. (trong trường hợp này, có nhiều thư mục con có tên nghệ sĩ âm nhạc /home/myid/Music/và sau đó các tệp FLAC đều ở các cấp thư mục con khác nhau. Vì tôi không cần các thư mục nghệ sĩ nhưng muốn có tất cả các tệp FLAC vào một thư mục tại/home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

Sau đó, nó sẽ hiển thị tất cả các tập tin FLAC.


những gì ;làm gì?
Francesco Boi

@FrancescoBoi nó đảm bảo đợi cho đến khi lệnh bash trong cùng dòng hoàn thành công việc của nó. và sau đó chuyển sang dòng lệnh bash tiếp theo. Điều này hữu ích cho các lệnh có chứa các tập lệnh như .pl hoặc python vì bash sẽ chỉ chạy nó và sau đó nhảy sang dòng tiếp theo, vì vậy để an toàn, tôi sử dụng; sau các lệnh mất thời gian hoặc tập lệnh, trong trường hợp bash bỏ qua nó.
Seandex

0

Là một bash hack, bạn có thể sử dụng sức mạnh của tar:

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

Điều này có lợi thế là nó không phụ thuộc vào phần mở rộng tệp, vì nó sử dụng filelệnh để chọn các tệp để di chuyển và nó giữ nguyên cấu trúc thư mục, nhưng nó không hoạt động với các đường dẫn chứa khoảng trắng.

Cuối cùng rmlà để xóa các tập tin gốc (becouse @InquilineKea nói rằng anh ấy không quan tâm đến thư mục gốc trong bình luận).

Tất nhiên điều này đặc biệt phù hợp nếu nguồn gốc / và đích / thư mục nằm trên các đĩa khác nhau. Mặt khác, các giải pháp khác được đề xuất là hiệu quả hơn (ngay cả khi chúng dựa vào các quy ước đặt tên, thay vì filenội dung của).


0

Giả sử bạn có các phiên bản GNU của find và mv, các cách sau sẽ hiệu quả hơn các câu trả lời dựa trên tìm kiếm hiện có:

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

Sử dụng a +ở cuối find -exec có nghĩa là một danh sách các tệp sẽ được chuyển đến lệnh mv, thay vì thực thi một lệnh mv cho mỗi tệp được tìm thấy. Tuy nhiên, một hạn chế của điều này là bạn chỉ có thể đặt '{}' ở cuối lệnh, điều này bắt buộc phải sử dụng tùy chọn thư mục mv --target và theo như tôi biết đó là GNU-ism.

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.