ফাইল সংগ্রহ থেকে একটি এলোমেলো নমুনা সংগ্রহ করার সেরা পদ্ধতি


23

ধরুন এখানে একটি ডিরেক্টরি রয়েছে যেখানে 300 টি ডাটা ফাইল রয়েছে। আমি এলোমেলোভাবে ফাইলগুলির 200 টি নির্বাচন করতে এবং তাদের অন্য ডিরেক্টরিতে স্থানান্তর করতে চাই। ইউনিক্স / লিনাক্সের অধীনে এটি করার কোনও উপায় আছে কি?


আর সম্ভবত চোখের পলকে এই কাজটি করতে পারে list.files()...
sr_

4
আমি অস্পষ্টভাবে একসাথে প্লাগ করব shufএবং head(বা কেবল ব্যবহারের shuf -nজন্যই ম্যান পৃষ্ঠাটি পড়া উচিত ছিল ...)
উলরিচ শোয়ার্জ

উত্তর:


32

যদি আপনার সিস্টেমে থাকে তবে shufআপনি এটি বেশ সুবিধাজনকভাবে ব্যবহার করতে পারেন (এমনকি কুৎসিত ফাইলের নামও পরিচালনা করছেন):

shuf -zen200 source/* | xargs -0 mv -t dest

আপনার যদি না থাকে shufতবে sortযা লাগে -R, তা কাজ করা উচিত:

find source -type f -print0 | sort -Rz | cut -d $'\0' -f-200 | xargs -0 mv -t dest

7
হ্যাঁ হ্যাঁ, কারণ বাছাইয়ের কোনও সরঞ্জামের চেয়ে আর কোথা থেকে কেউ বদলে যাবে। (কমপক্ষে shufবলা হয় নি trosকারণ এটি বাছাইয়ের বিপরীতে কাজ করে))
উলিরিচ শোয়ার্জ 10:58

2
বাছাইয়ের বিপরীত বলে কোনও জিনিস নেই (একই অর্থে "কোনও আবহাওয়া নেই" বলে কিছু নেই)। র্যান্ডম এখনও বাছাই করা হয়, এটি কেবল এলোমেলোভাবে বাছাই করা হয়।
প্লটর

1
"-Zen200" কী? এটি শফের জন্য বা ইন্টারনেটে কোথাও কোনও নথিতে নেই, তবে আপনার উদাহরণটি এটি ছাড়া কার্যকর হয় না। বেশ রহস্যময়।
সিগম্যাক্স

2
@ সিগম্যাক্স সত্যই, বেশ জেন, তাই না। ইঙ্গিত: এটি 3 পৃথক পতাকা।
কেভিন


2

বাশ-এ "ফাইল" নামে একটি অ্যারেতে সমস্ত ফাইলের নাম রাখুন:

files=( * )

অ্যারের আকার:

echo ${#files[@]}

তাদের মধ্যে 2/3 নমুনা আকার হিসাবে সংজ্ঞায়িত করুন:

take=$((2*${#files[@]}/3)) 

for i in $(seq 1 $take)
do
    r=$((RANDOM%${#files[@]})) 
    echo ${files[r]}
done

এটি সদৃশ নির্বাচন করবে এবং ফাঁকা এবং এই জাতীয় ফাইলের সাথে পরীক্ষা করা হবে না

সদৃশগুলি এড়ানোর সহজতম উপায় হ'ল সমস্ত ফাইলের পুনরাবৃত্তি করা এবং 2/3 সুযোগ নিয়ে প্রত্যেককে বাছাই করা, তবে এটি অগত্যা 200 ফাইলগুলিকে নিয়ে যাবে না।

এটি যদি কোনও ফাইল তালিকা থেকে বেছে নেওয়া হয় এবং আপনার প্রয়োজনীয়তা পূরণ করে:

#!/bin/bash
files=( * )
# define 2/3 of them as sample size:
take=$((2*${#files[@]}/3)) 

while (( i < $take ))
do
    r=$((RANDOM%${#files[@]})) 
    f=${files[r]}
    if [[ -n $f ]]
    then 
        i=$((i+1))    
        echo ${files[r]}
        unset files[r]    
    fi
done

আপনি একই ফাইলটি একাধিকবার নির্বাচন করতে পারেন।
গ্লেন জ্যাকম্যান

খুব সুন্দর শেল স্ক্রিপ্ট। আপনার 200 টি ফাইল না পাওয়ার সমস্যাটি পেতে আপনি সম্ভবত জলাধার স্যাম্পলিংটি ব্যবহার করতে চান: en.wikedia.org/wiki/Resservoir_sampling আমি দুর্বল হয়ে যাচ্ছি এবং এর কোনও শেল স্ক্রিপ্ট উদাহরণ অন্তর্ভুক্ত করব না।
ব্রুস এডিগার

@glennjackman: আমি তাই লিখেছি, হ্যাঁ। অ্যারে থেকে এন্ট্রিগুলি কীভাবে সরানো যায় তা নির্ধারণ করার জন্য কয়েক মিনিটের প্রয়োজন।
ব্যবহারকারী অজানা

মাইনর ক্যাভিয়েট: $RANDOMকেবলমাত্র 0 থেকে 32767 এর মধ্যে মান থাকতে পারে, সুতরাং আপনার কাছে 32768 এর বেশি ফাইল থাকলে এটি সঠিকভাবে কাজ করবে না। এছাড়াও, প্রথম ফাইলগুলির প্রতি আনয়ন পক্ষপাতদুষ্ট।
l0b0

@ l0b0: প্রয়োজনীয়তাগুলি যেখানে 300 থেকে 200 বাছাই করতে হবে the ফাইলগুলি যদি বর্তমান ডিরেক্টরিতে না থাকে তবে একটি ফাইল সার্ভারে থাকে তবে এটি খুব কার্যকর হবে না। বিভিন্ন প্রয়োজনীয়তা, বিভিন্ন উত্তর।
ব্যবহারকারী অজানা

2

এটি যদি পরিসংখ্যানগতভাবে এলোমেলোভাবে প্রয়োজন হয় তবে আপনার ব্যবহার করা উচিত নয় RANDOM % ${#keys[@]}। বিবেচনা:

  1. $RANDOM 32768 অনন্য মান আছে
  2. প্রথম নির্বাচনটি 300 উপাদানের মধ্যে 1
  3. 32768 = 109 * 300 + 68

সুতরাং, প্রথম আইটেমটি নির্বাচন করার সময়, 68 টি প্রথম উপাদানগুলির প্রত্যেকের জন্য একটি 110/32768 0.3 = 0.33569% সুযোগ রয়েছে এবং অন্য 232 উপাদানগুলির প্রত্যেকটির জন্য 109/32768 0.3 = 0.33264% সুযোগ রয়েছে। বাছাইয়ের বিভিন্ন সম্ভাবনার সাথে কয়েকবার পুনরাবৃত্তি করা হয়, তবে যখনই প্রথম উপাদানগুলির প্রতি পক্ষপাতিত্ব করা হয় 32768 % ${#keys[@]} -ne 0, তাই ত্রুটিযুক্ত যৌগগুলি।

এটি পক্ষপাতহীন হওয়া উচিত এবং যে কোনও ফাইলের সাথে কাজ করে:

while IFS= read -r -d '' -u 9
do
    mv -- "$REPLY" /target/dir
done 9< <(find /source/dir -mindepth 1 -print0 | shuf -n 200 -z)

2

কেভিনের সমাধানটি দুর্দান্ত কাজ করে! অন্য কিছু যা আমি প্রচুর ব্যবহার করেছি কারণ এটি আমার মাথার উপরের অংশ থেকে মনে রাখা সহজ হয় এরকম কিছু:

cp `ls | shuf -n 200` destination

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.