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?
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?
Câu trả lời:
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 globstar
trướ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 globstar
trướ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 {} \;
find
Lệnh đầu tiên ở trên hoạt động trong bash, nhưng phải đổi thành find . -name
vv để làm cho nó hoạt động.
.
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.
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.
Đ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/" ";"
*.flac
thành bất cứ điều gì như *.zip
trong trường hợp của bạn. Hoặc *.doc
bất kỳ phần mở rộng hoạt động.mv
là 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.
;
làm gì?
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 file
lệ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 rm
là để 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ì file
nội dung của).
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.