Làm cách nào tôi có thể di chuyển tất cả các tệp trong thư mục con theo cách đệ quy vào một thư mục?


10

Tôi đang cố gắng thu thập tất cả các tệp trong thư mục hiện tại và tất cả các thư mục con vào một thư mục. Tôi đang thử một cái gì đó như sau

find -type f -exec mv {} collection/{} \; 

lệnh trên sẽ không hoạt động vì lệnh thứ hai {}cung cấp đường dẫn đầy đủ, làm cách nào tôi có thể thu thập tất cả các tệp?

Câu trả lời:


14

Xóa {}từ mv, mvsẽ lấy nó làm thư mục đích bỏ qua mọi thư mục mẹ:

find -type f -exec mv {} collection/ \;

ohh điều đó đã không xảy ra với tôi. cảm ơn :)
Bunny Bunny

Như tôi nói trong câu trả lời của mình cho câu hỏi, đây có khả năng là một ý tưởng tồi. Có lẽ sử dụng các đối số -maxdepth 1sẽ giúp.
loevborg

Nghĩ về nó, có vẻ như tôi đã đọc sai câu hỏi của bạn :) Xin lỗi.
loevborg

@loevborg: Bây giờ tôi đã thêm "đệ quy" vào tiêu đề. Nếu vẫn còn nhầm lẫn, vui lòng chỉnh sửa và cải thiện nó :)
Lekensteyn

1
một biến thể nhanh hơn của câu trả lời này làfind -type f -print0|xargs -0r mv -it colection/
hildred

5

Thay vì sử dụng find(công việc này hoạt động tốt), bạn cũng có thể sử dụng shell cho mục đích này.

Giả sử bạn muốn tất cả các tệp từ $ PWD đến $ DEST. Nỗ lực tự nhiên sẽ là:

mv $PWD/* $DEST

Cái này hoạt động ra sao? Biểu thức "$ PWD / *" mở rộng thành tên của tất cả các tệp trong thư mục đó. Tính năng vỏ này được gọi là "continbing". Đối số cuối cùng mvlà thư mục đích. Nếu bạn có rất nhiều tệp, điều này sẽ không hoạt động vì độ dài của dòng lệnh bị giới hạn.

Nhưng giải pháp có vấn đề là nó bỏ qua các tệp chấm - hoặc các tệp, tệp và thư mục "ẩn" có tên bắt đầu bằng dấu ".". Để giải quyết điều này, bạn phải nói với trình bao của bạn bao gồm các dotfiles khi tạo khối. Để làm điều này, sử dụng

shopt -s dotglob

khi sử dụng bash(và bạn có thể sử dụng bashtrừ khi bạn thay đổi mặc định). Trong shell này, lệnh trên cũng sẽ hoạt động cho dotfiles.

Như một bên, trong zsh, bạn có tùy chọn để chọn điều này trên cơ sở từng trường hợp. Để làm điều này, đặt

setopt extendedglob

trong của bạn .zshrc. Sau đó, bạn có thể sử dụng

mv $PWD/*(D) $DEST

để di chuyển tất cả các tệp, bao gồm cả dotfiles. ("D" có tác dụng tạm thời bật tùy chọn "GLOB_DOTS").

Bây giờ câu hỏi ban đầu là để di chuyển tất cả các tệp thông thường (không phải thư mục) từ tất cả các thư mục con và thư mục con của chúng sang một thư mục. Điều này có thể được thực hiện với zsh:

mv $PWD/**/*(D.)

Ở đây biểu thức **/*làm cho quả cầu xuống theo cách đệ quy thành các thư mục con. Có Dnghĩa là "cũng chọn dotfiles '; .phương tiện" chỉ chọn các tệp thông thường, không phải các thư mục ".


tôi cũng muốn truy cập lại vào tất cả các thư mục con, nhưng cảm ơn mọi cách thông tin đều hữu ích, gặp tình huống này quá nhiều lần :)
Bunny Rabbit

Trên thực tế, find không phải là quá mức cho việc này, globalbing sẽ chọn tất cả các kết quả khớp, không chỉ các tệp, mà cả các thư mục. Nếu bạn lo lắng về hiệu suất, bạn cũng có thể sử dụng một cái gì đó như : find -type f -exec mv -t collection/ {} +. Tham khảo trang hướng dẫn về cách làm việc này.
Lekensteyn

Lekensteyn, bạn nói đúng. Tôi đã cập nhật câu trả lời mà tôi đã hiểu câu hỏi.
loevborg

2
Câu trả lời tuyệt vời, quá tệ là nó không liên quan đặc biệt đến câu hỏi :).
crazy2be
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.