Làm cách nào tôi có thể tìm kiếm các tệp trong tất cả các thư mục con bằng shell và sau đó sao chép các tệp đó?


8

Làm cách nào tôi có thể tìm thấy các tệp * .mp3 bằng lệnh đệ quy như ls -R *.mp3trong thư mục chứa một số thư mục con và cuối cùng sao chép các tệp này trong thư mục mà tôi chọn.

Cảm ơn sự hỗ trợ của bạn.

Câu trả lời:


14

Lệnh là:

find /path/to/directory -name "*.mp3" -exec cp {} /some/other/dir/ \;

Thay thế:

find /path/to/dir/ -name '*.mp3' | xargs cp -t /target/

Thí dụ:

alex@MaD-pc:~/test$ ls
1  2  3
alex@MaD-pc:~/test$ ls 1 2 3
1:
1.txt  2.mp3  3.txt

2:
4.txt  5.mp3  6.txt

3:
alex@MaD-pc:~/test$ find . -name "*.mp3" -exec cp {} 3/ \;
alex@MaD-pc:~/test$ ls 3
2.mp3  5.mp3

Để biết thêm thông tin:

man find

Các thẩm phán cũng sẽ chấp nhận:find /path/to/dir/ -name '*.c' | xargs cp -t /target/
Oli

Tôi là một trong những thẩm phán và tôi từ chối giải pháp này 8-) Cảm ơn vì nhận xét, tôi sẽ thêm nó :)
hytromo

1
xargsthường là nhanh hơn rất nhiều . Tôi vừa mới chạy thử nghiệm nhanh ở đây để tìm tải tập tin c và chạy ls -ltrên chúng. Đó là 0m2.420 cho xargsvà 0m25.494 cho -exec... Rõ ràng trong trường hợp này, cphoạt động sẽ mất phần lớn thời gian nên có thể không có vấn đề gì nhưng nó đáng để lưu ý.
Oli

Tôi khuyên bạn nên thêm -n`` switch to the lệnh cp` để tránh ghi đè trong trường hợp tên trùng lặp (hoặc viết tập lệnh kiểm tra trùng lặp trước khi sao chép và đổi tên mục tiêu khi cần thiết)
Elder Geek

2

Ngoài ra còn có một cách khác để làm điều đó mà tôi nghĩ sẽ phù hợp với mục đích của bạn một cách hoàn hảo. Bạn có thể kết hợp findvới một whilevòng lặp và thậm chí không cần sử dụng một trong hai exechoặc xargscả. Ví dụ, nếu bạn muốn sao chép mp3stừ thư mục tải xuống vào thư mục nhạc của mình, bạn sẽ sử dụng tập lệnh sau mà tôi đã sử dụng nhiều lần.

Bạn có thể sửa đổi nó theo cách bạn muốn bằng cách thay đổi các thư mục findtìm kiếm và đặt các tệp kết quả vào; nếu không có thư mục nào được nêu, findsẽ tìm kiếm toàn bộ thư mục nhà. Bạn cũng có thể thay đổi cpthành mvhoặc các lệnh khác. Nó khá nhanh, vì tôi vừa thử nó với 3945 .jpgtệp! Sao chép nó vào một trình soạn thảo văn bản, lưu nó và sau đó làm cho nó có thể thực thi được bằng cách chạy chmod +x myscript.

#!/bin/bash
# a script to recursively find and copy files to a desired location
find ~/Downloads -type f -iname '*.mp3' -print0 |
while IFS= read -r -d '' f; 
do cp -- "$f" ~/Music ;
done

Tại Bash Bash được ghi chú này, nó cho thấy sự kết hợp giữa whilevòng lặp và readcác lệnh để xử lý đầu ra của findlệnh hữu ích như thế nào ; và cách tôi đã thực hiện nó đảm bảo rằng tập lệnh sẽ không bị hỏng nếu nó bắt gặp tên tệp có khoảng trắng hoặc các ký tự bất ngờ hoặc đặc biệt khác.

Để biết thêm thông tin chung về findlệnh, hãy nhập vào thiết bị đầu cuối man findhoặc xem các trang hướng dẫn Ubuntu trực tuyến . Đối với một giới thiệu tuyệt vời về việc sử dụng tìm, xem bài viết này là tốt.


không find ~/Downloads -type f -iname '*.mp3' | while read mp3file; do cp "$mp3file" ~/Music; doneđơn giản hơn sao?
steabert

Phương pháp của tôi đại diện cho thực tiễn tốt nhất và ngăn chặn tập lệnh bị phá vỡ, như được lưu ý tại liên kết tôi đã trích dẫn.

ah, tôi hiểu rồi, việc đó xử lý các ký tự đặc biệt, cảm ơn vì liên kết :)
steabert

Tôi khuyên bạn nên thêm -n`` switch to the lệnh cp` để tránh ghi đè trong trường hợp tên trùng lặp (hoặc viết tập lệnh kiểm tra trùng lặp trước khi sao chép và đổi tên mục tiêu khi cần thiết)
Elder Geek
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.