Làm cách nào để xóa tất cả các tập tin theo thứ tự ngẫu nhiên?


7

Tôi có một tập hợp các tệp, tất cả được đặt tên theo quy ước file_[number]_[abcd].bin(trong đó [số] là một số trong phạm vi kích thước 0 của ổ đĩa tính bằng MB). tức là có file_0_a.bin, file_0_b.bin, file_0_c.binfile_0_d.binsau đó là 0sẽ trở thành một 1và vân vân.

Số lượng tệp được tìm ra tại thời điểm chạy dựa trên kích thước của phân vùng. Tôi cần xóa tất cả các tệp đã được tạo, nhưng theo cách giả ngẫu nhiên. trong các khối có kích thước mà tôi cần để có thể chỉ định , tức là nơi có 1024 tệp, xóa 512, sau đó xóa 512 khác.

Tôi có chức năng sau đây để thực hiện nó, cái mà tôi gọi là số lần cần thiết, nhưng nó sẽ dần dần ít có khả năng tìm thấy một tệp tồn tại, đến mức mà nó có thể không bao giờ hoàn thành. Rõ ràng, điều này có phần ít hơn lý tưởng.

Phương pháp khác mà tôi có thể sử dụng để xóa tất cả các tệp theo thứ tự ngẫu nhiên là gì?

deleteRandFile() #$1 - total number of files
{
    i=$((RANDOM%$1))
    j=$((RANDOM%3))
    file=""

    case $j in
    0)
        file="${dest_dir}/file_${i}_a.bin";;
    1)
        file="${dest_dir}/file_${i}_b.bin";;    
    2)
        file="${dest_dir}/file_${i}_c.bin";;
    3)
        file="${dest_dir}/file_${i}_d.bin";;
    esac

    if ! [[ -f $file ]]; then
        deleteRandFile $1
    else
        rm $file
    fi

    return 0;
}

Chỉnh sửa: Tôi đang cố gắng xóa theo thứ tự ngẫu nhiên để tôi có thể phân chia các tệp nhiều nhất có thể. Đây là một phần của tập lệnh bắt đầu bằng cách lấp đầy ổ đĩa với các tệp 1MB và xóa chúng, 1024 tại một thời điểm, sau đó lấp đầy 'khoảng trống' với tệp 1 1GB. Rửa sạch và lặp lại cho đến khi bạn có một số tệp 1GB rất phân mảnh.


Có lẽ nó sẽ hữu ích nếu bạn có thể giải thích tại sao nó quan trọng theo thứ tự bạn xóa các tệp.
Nate Eldredge

@NateEldredge Chắc chắn, uh ... Tôi đang cố gắng phân mảnh ổ cứng và giết hệ thống tệp. Tôi có lý do của tôi.
Yann

Trong zsh, bạn sẽ sử dụng *.bin(o+functionName)ký hiệu như trong unix.stackexchange.com/a/9831
ignis

Câu trả lời:


13

Nếu bạn muốn xóa tất cả các tệp, thì trên hệ thống GNU, bạn có thể thực hiện:

cd -P -- "$destdir" &&
  printf '%s\0' * | # print the list of files as zero terminated records
    sort -Rz |      # random sort (shuffle) the zero terminated records
    xargs -r0 rm -f # pass the input if non-empty (-r) understood as 0-terminated
                    # records (-0) as arguments to rm -f

Nếu bạn muốn chỉ xóa một số lượng nhất định phù hợp với biểu thức chính quy, bạn sẽ chèn một cái gì đó như thế này vào giữa sortxargs:

awk -v RS='\0' -v ORS='\0' -v n=1024 '/regexp/ {print; if (--n == 0) exit}'

Với zsh, bạn có thể làm:

shuffle() REPLY=$RANDOM
rm -f file_<->_[a-d].bin(.+shuffle[1,1024])

Tôi không cho rằng bạn muốn giải thích đầy đủ hơn một chút?
Yann

Tôi cần học cách gõ nhanh hơn hoặc bỏ qua các hàng đợi đánh giá để nhận được câu trả lời trong ;-)
Anthon

Điều này có vẻ khá tốt, bạn có phiền đi sâu vào chi tiết hơn một chút về những gì xargs -r0lá cờ làm không?
Yann

Cảm ơn, điều cuối cùng là làm thế nào tôi cần phải thay đổi điều này để làm cho nó không xóa được cùng một lúc, nhưng xóa, nói, 1024 tại một thời điểm? Liệu đường ống thông qua một cái gì đó để có được 1024 mục đầu tiên phù hợp với công việc regex?
Yann

1
@OlivierDulac, không. printf '%s\0' *định dạng từng đối số như %s\0vậy findngoại trừ việc nó loại trừ các tệp chấm, sắp xếp danh sách, không phân nhánh một quá trình. Và bạn có thể làm được printf '%s\0' file_*_[a-d].bin. findcó thể tốt hơn nếu bạn chỉ muốn các tệp thông thường mặc dù bạn cũng có thể sử dụng zsh và vòng loại toàn cầu của nó.
Stéphane Chazelas

11

Đây là một giải pháp thay thế tiềm năng bằng cách sử dụng findshuf:

$ find $destdir -type f | shuf | xargs rm -f

Điều này sẽ tìm thấy tất cả các tệp trong $destdirvà sau đó sử dụng shuflệnh để xáo trộn thứ tự của chúng, và sau đó chuyển danh sách để xargs rm -fxóa.

Để cổng có bao nhiêu tệp bị xóa:

$ find $destdir -type f | shuf | head -X | xargs rm -f

Trong trường hợp -Xlà số lượng tập tin mà bạn muốn xóa, ví dụ, head -100.


Đó là một câu trả lời hay, nhưng nó không cho phép tôi chỉ định có bao nhiêu tệp cần xóa. (tôi cũng không có shuftrên hệ thống, nhưng tôi không chỉ định những gì tôi có, vì vậy điều đó không ngăn cản đây là một câu trả lời hay)
Yann

Tôi bối rối, tại sao bạn cần chỉ định một số cho chức năng xóa?
slm

1
@ Yann4 Tôi bối rối nhưng tò mò về điều đó "không liên quan đến việc biên dịch lại kernel" - đó có phải là một loại meme mà tôi đã bỏ lỡ không?
Volker Siegel

2
Câu trả lời này không an toàn như được viết, ít nhất là nói chung. findxuất ra các chuỗi ký tự được phân tách bằng các dòng mới và xargsđọc một danh sách tên được phân tách bằng vỏ, được phân tách bằng khoảng trắng làm đầu vào. Một tên độc hại trong đầu vào có thể lừa nó xóa một cái gì đó rất khác với những gì bạn định xóa.
R .. GitHub DỪNG GIÚP ICE

2
@R - xem xét các yêu cầu về định dạng tên tệp mà OP đang sử dụng. Điều này là hoàn toàn an toàn cho rằng!
slm
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.