एक निर्देशिका से सूची यादृच्छिक फ़ाइलें


14

क्या मानक लिनक्स कमांड्स का उपयोग करके निर्देशिका से 30 यादृच्छिक फ़ाइलों को कहने का एक सेट सूचीबद्ध करने का एक तरीका है? (इन zsh)

यहाँ वर्णित शीर्ष उत्तर मेरे लिए काम नहीं करता है ( sortविकल्प को नहीं पहचानता है -R)


मैं उत्सुक हूं कि आप किस ओएस पर हैं।
ixtmixilix

जवाबों:


7

चूँकि आप zsh का उल्लेख कर रहे हैं:

rand() REPLY=$RANDOM
print -rl -- *(o+rand[1,30])

आप बदल सकते हैं printकहते हैं के साथ ogg123और *कहते हैं के साथ**/*.ogg


19

lsआउटपुट को पाइप करने की कोशिश करें shuf, जैसे

$ touch 1 2 3 4 5 6 7 8 9 0
$ ls | shuf -n 5
5
9
0 
8
1

-nध्वज को निर्दिष्ट करता है कि आप कितने यादृच्छिक फ़ाइलें चाहते हैं।


command not found(स्थापित नहीं): /
एमिलियो वाज़केज़-रीना

अजीब ... यह कोरुटिल का एक हिस्सा होना चाहिए। यदि आपका कोरुटिल पुराना है, तो कमांड वहाँ नहीं होगा।
रेनैन

6
यह त्वरित और गंदा तरीका है, और मैं इसका इस्तेमाल करूंगा, वह भी - एक बार की पटकथा के लिए। कुछ अधिक टिकाऊ के लिए, के उत्पादन को पार्स करने से बचेंls
जानमोसन

@janmoesen मुझे इस बारे में पता नहीं था। धन्यवाद!
रेन

@ रेनन हर यूनिक्स में डिफ़ॉल्ट रूप से जीएनयू कोरुटिल स्थापित नहीं है।
Kusalananda

2

एक छोटे से पर्ल के साथ इसे हल करना काफी आसान है। वर्तमान निर्देशिका से यादृच्छिक पर चार फ़ाइलों का चयन करें:

perl -MList::Util=shuffle -e 'print shuffle(`ls`)' | head -n 4

हालांकि उत्पादन के उपयोग के लिए, मैं एक विस्तारित स्क्रिप्ट के साथ जाऊंगा, जो lsआउटपुट पर निर्भर नहीं करता है , किसी भी dir को स्वीकार कर सकता है, आपके आर्ग की जांच कर सकता है, आदि ध्यान दें कि यादृच्छिक चयन स्वयं अभी भी केवल कुछ पंक्तियों का है।

#!/usr/bin/perl    
use strict;
use warnings;
use List::Util qw( shuffle );

if ( @ARGV < 2 ) {
    die "$0 - List n random files from a directory\n"
        . "Usage: perl $0 n dir\n";
}
my $n_random = shift;
my $dir_name = shift;
opendir(my $dh, $dir_name) || die "Can't open directory $dir_name: $!";

# Read in the filenames in the directory, skipping '.' and '..'
my @filenames = grep { !/^[.]{1,2}$/ } readdir($dh);
closedir $dh;

# Handle over-specified input
if ( $n_random > $#filenames ) {
    print "WARNING: More values requested ($n_random) than available files ("
          . @filenames . ") - truncating list\n";
    $n_random = @filenames;
}

# Randomise, extract and print the chosen filenames
foreach my $selected ( (shuffle(@filenames))[0..$n_random-1] ) {
    print "$selected\n";
}

इम्हो ए पर्ल-स्क्रिप्ट एक 'मानक यूनिक्स कमांड' नहीं है। यह समस्या किसी भी उच्च-स्तरीय स्क्रिप्टिंग भाषा जैसे पर्ल, पायथन या रूबी में हल करना आसान है, लेकिन अधिक दिलचस्प है अगर यह सीधे कमांडलाइन पर है।
गेरिट

1
@gerrit - मैं आपकी बात लेता हूं। मैंने इसे प्रदान किया क्योंकि पसंदीदा उत्तर (उपयोग करना shuf) ओपी के लिए पर्याप्त नहीं था। के रूप में क्या है और मानक यूनिक्स नहीं है - पर्ल हर जगह मौजूद है, और यह समस्या को सफलतापूर्वक और मजबूती से हल करता है। अगर मैं इसे पर्ल वन-लाइनर के रूप में देता, तो क्या इसे 'कमांड लाइन' के रूप में गिना जाता? क्या वास्तव में पर्ल शक्तिशाली है, इस उत्तर के अस्तित्व के खिलाफ एक तर्क है?
ire_and_curses

मैं कहूंगा कि यह एक अलग सवाल का जवाब है। निश्चित रूप से किसी भी पूरी तरह से चित्रित प्रोग्रामिंग भाषा में यह समस्या तुच्छ है, मेरे लिए सवाल का दिलचस्प हिस्सा यह है कि अगर यह किया जा सकता है / बिना / एक ~ 20 LOC स्क्रिप्ट का सहारा लिए; स्क्रिप्टिंग भाषाएं शक्तिशाली हैं, लेकिन मुझे नहीं लगता कि पर्ल एक कमांड के रूप में वर्गीकृत करता है (जैसे कि ओपी पूछ रहा था, और नहीं, यदि आप एक 200-चरित्र कमांडलाइन पर्ल को आमंत्रित करते हैं तो मेरी भी यही राय होती)।
गुरट

@gerrit - शायद मैं स्पष्ट हो सकता हूं। मेरे संपादन पर एक नज़र डालें: perl -MList::Util=shuffle -e 'print shuffle(ls )' | head -n 4क्या यह अधिक पसंद है जो आप देख रहे थे?
ire_and_curses 15

हाँ, मैंने अपने डाउनवोट को हटा दिया जो कि वास्तव में थोड़ा कठोर था।
gerrit

1

एक सरल समाधान जो एलएस के पार्सिंग से बचा जाता है और रिक्त स्थान के साथ भी काम करता है:

shuf -en 30 dir/* | while read file; do
    echo $file
done

जैसा कि अन्य टिप्पणियों में देखा गया है, ओपी बिना सिस्टम के है shuf
Kusalananda

बचना shufप्रश्न में उल्लेख नहीं है। यह उत्तर अभी भी अन्य उपयोगकर्ताओं के लिए उपयोगी होगा।
स्काइ

0

Zsh के अलावा और कुछ नहीं का उपयोग कर एक oneliner:

files=(*); for x in {1..30}; do i=$((RANDOM % ${#files[@]} + 1)); echo "${files[i]}"; done

बाश में वही, जहाँ सरणी सूचक शून्य-आधारित हैं:

files=(*); for x in {1..30}; do i=$((RANDOM % ${#files[@]})); echo "${files[i]}"; done

ध्यान दें कि न तो संस्करण डुप्लिकेट को ध्यान में रखता है।


1
यह एक ही फ़ाइल को एक से अधिक बार सूचीबद्ध कर सकता है। इससे बचना समस्या का एक महत्वपूर्ण हिस्सा है।
गिल्स एसओ- बुराई को रोकना '

गिलेस: काफी सही है, यही कारण है कि मैंने कहा "ध्यान दें कि न तो संस्करण डुप्लिकेट को ध्यान में रखता है।" आप इसे अभी भी शुद्ध बैश में कर सकते हैं, यदि आप समय की जटिलता के बारे में परवाह नहीं करते हैं और हर बार जब आप इसके साथ एक यादृच्छिक हटाते हैं तो सरणी को फिर से बनाते हैं। एक-लाइनर के करीब भी नहीं, फिर भी, लेकिन निश्चित रूप से एक आवश्यकता नहीं थी।
जानमोसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.