2012-01-31 36 views
6

Tôi có thư mục chứa hơn 27000 hình ảnh.Làm thế nào để di chuyển tất cả các tệp của một thư mục vào nhiều thư mục với một số lượng tệp nhất định?

Tôi muốn chia các tệp này thành các thư mục có chứa khoảng 500 hình ảnh.

Việc phân loại chúng không quan trọng, tôi chỉ muốn tách chúng ra.

+3

Những gì bạn đã cố gắng cho đến nay? Đây không phải là trang web "cung cấp cho tôi codez". Bạn phải thể hiện rằng bạn đã nỗ lực SOME ít nhất. –

Trả lời

6

Sau đây nên làm việc:

dest_base="destination" 
src_dir="src/" 

filesperdir=500 
atfile=0 
atdir=0 
for file in $src_dir/*; do 
    if ((atfile == 0)); then 
     dest_dir=$(printf "$dest_base/%0.5d" $atdir) 
     [[ -d $dest_dir ]] || mkdir -p $dest_dir 
    fi 
    mv $file $dest_dir 
    ((atfile++)) 
    if ((atfile >= filesperdir)); then 
     atfile=0 
     ((atdir++)) 
    fi 
done 
+0

Điều đó hoạt động hoàn hảo. Cảm ơn! – cesmarch

+0

Điều này có đức hạnh thực sự làm việc, mặc dù nếu '$ src_dir/*' quá dài hoặc nếu dest_base được cấu hình để có một khoảng trống trong đó hoặc nếu bất kỳ tệp nào có dấu cách hoặc các ký tự đặc biệt khác trong tên vẫn sẽ là vấn đề. – Sorpigal

+0

Lưu ý: Đây là tập lệnh bash (không phải là chữ viết tắt) – Tom

-1

Bạn có thể bắt đầu với điều này:

mkdir new_dir ; find source_dir | head -n 500 | xargs -I {} mv {} new_dir 

này sẽ tạo new_dir và di chuyển 500 file old_dir-new_dir. Bạn vẫn phải tự gọi điều này cho các giá trị khác nhau của new_dir cho đến khi thư mục cũ trống và bạn phải xử lý các tên tệp chứa các ký tự đặc biệt.

0

OK, các tập tin tạm thời các cửa hàng giải pháp sau đây với danh sách 500 tên tập tin. Thích nghi nó khi bạn cần. Đầu tiên chúng tôi liệt kê tất cả các file trong thư mục hiện hành, chia 500 500, và lưu trữ các kết quả trong outputXYZ. * File

ls | split -l 500 - outputXYZ. 
# Then we go through all those files 
count=0 
for i in outputXYZ.*; do 
    ((count++)) 
    # We store the result in dir.X directory (created in current directory) 
    mkdir dir.$count 2>/dev/null 

    # And move those files into it 
    cat $i | xargs mv -t dir.$count 

    # remove the temp file 
    rm $i 
done 

Cuối cùng, bạn đã có tất cả các hình ảnh của bạn trong danh bạ dir.1 (1. .500), dir.2 (501..1000), dir.3, v.v.

+1

Lỗi! Sử dụng sai 'ls', không được xác nhận' rm $ i' (!), V.v. – Sorpigal

+0

Xin chào, tôi không nhận được bình luận "Không hợp lệ của chúng tôi về ls". – huelbois

+2

Đầu ra của 'ls' không đáng tin cậy cho bất kỳ mục đích nào khác ngoài mục đích sử dụng của con người. Nếu bạn cần một danh sách các tập tin trong một định dạng đáng tin cậy, bạn nên sử dụng 'find'. Việc phân tích đầu ra 'ls' sẽ phá vỡ trên một số lượng lớn các trường hợp góc. – Sorpigal

9

A "đơn giản" find/xargs sẽ làm gì:

find -maxdepth 1 -type f -print0 | xargs -r -0 -P0 -n 500 sh -c 'mkdir newdir.$$; mv "[email protected]" newdir.$$/' xx 

Giải thích:

  • tìm
    • -maxdepth 1 ngăn chặn tìm từ đệ quy đi qua bất kỳ thư mục, an toàn, không cần thiết nếu bạn biết bạn không có thư mục
    • -type f chỉ tìm các tệp
    • -print0 tập tin riêng biệt với null char thay vì LF (để xử lý tên lạ)
  • xargs
    • -r không chạy với danh sách đối số rỗng
    • -0 đọc các tập tin tách ra với null
    • -P0 tạo bao nhiêu quy trình khi bạn cần
    • -n 500 chạy từng quy trình với 500 đối số
  • sh
    • -c kịch bản dòng lệnh chạy được cung cấp như là đối số tiếp theo
    • mkdir newdir.$$ tạo ra một thư mục mới kết thúc với quá trình shell PID
    • mv "[email protected]" newdir.$$/ di chuyển các đối số của kịch bản (mỗi trong số họ trích dẫn) để thư mục mới được tạo ra
    • xx tên cho tập lệnh được cung cấp (Xem sh thủ công)

Lưu ý rằng đây là không điều mà tôi sẽ sử dụng trong sản xuất, nó dựa chủ yếu vào trên thực tế là $$ (pid) sẽ khác nhau cho mỗi quá trình được thực hiện bởi xargs

Nếu bạn cần các tập tin sắp xếp bạn có thể trow một sort -z giữa tìm một xargs.

Nếu bạn muốn tên thư mục có ý nghĩa hơn bạn có thể sử dụng một cái gì đó như thế này:

echo 1 >../seq 
find -maxdepth 1 -type f -print0 |sort -z | xargs -r -0 -P1 -n 500 sh -c 'read NR <../seq; mkdir newdir.$NR; mv "[email protected]" newdir.$NR/; expr $NR + 1 >../seq' xx 
  • echo 1 > ../seq viết hậu tố thư mục đầu tiên trong một tập tin (chắc chắn rằng nó không có trong thư mục hiện hành)
  • -P1 yêu cầu xargs chạy một lệnh tại một thời điểm để ngăn chặn điều kiện chủng tộc
  • read NR <../seq đọc hậu tố thư mục hiện tại từ tệp
  • expr $NR + 1 >../seq viết hậu tố thư mục tiếp theo cho các hoạt động tiếp theo
  • sort -z loại các tập tin
+0

+1, đây chắc chắn là cách tiếp cận tôi sẽ sử dụng. – Sorpigal

Các vấn đề liên quan