फ़ाइलों की एक सूची डाउनलोड करने के लिए बिल्ली का पाइप आउटपुट


84

मेरे पास एक फ़ाइल में एक सूची यूआरएल है urls.txt। प्रत्येक पंक्ति में 1 URL है। मैं एक बार cURL का उपयोग करके सभी फ़ाइलों को डाउनलोड करना चाहता हूं। मैं सही एक लाइनर नीचे पाने के लिए प्रतीत नहीं कर सकते।

मैंने कोशिश की:

$ cat urls.txt | xargs -0 curl -O

लेकिन वह केवल मुझे सूची में अंतिम फ़ाइल देता है।


11
for i in $(cat urls.txt) ; do curl -O $i ; done
bkconrad

1
धन्यवाद, @bkconrad मेरे पास विंडोज पर नई trfor i in $(cat urls.txt) ; do curl -O $(echo $i | tr '\r' ' ') ; done
सुर्खियों के

जवाबों:


138

यह मेरे लिए काम करता है:

$ xargs -n 1 curl -O < urls.txt

मैं FreeBSD में हूँ। आपके xargs अलग तरीके से काम कर सकते हैं।

ध्यान दें कि यह क्रमिक रूप से चलता है curl, जिसे आप अनावश्यक रूप से भारी देख सकते हैं। यदि आप उस ओवरहेड में से कुछ को बचाना चाहते हैं, तो निम्नलिखित बाश में काम कर सकता है:

$ mapfile -t urls < urls.txt
$ curl ${urls[@]/#/-O }

यह आपकी URL सूची को एक सरणी में सहेजता है, फिर curlलक्ष्य को डाउनलोड करने के कारण सरणी को विस्तृत करता है । curlआदेश एकाधिक यूआरएल ले जा सकते हैं और उन सभी को लाने, मौजूदा कनेक्शन (HTTP / 1.1) रीसाइक्लिंग, लेकिन यह जरूरत -Oके क्रम में हर एक से पहले विकल्प डाउनलोड और सेव प्रत्येक लक्ष्य। ध्यान दें कि कुछ URL के अक्षर] आपके शेल के साथ बातचीत करने से बचने के लिए बच सकते हैं।

या यदि आप बैश के बजाय पोसिक्स शेल का उपयोग कर रहे हैं:

$ curl $(printf ' -O %s' $(cat urls.txt))

यह printfडेटा तर्कों की सूची को समाप्त करने के लिए प्रारूप पैटर्न को दोहराने के व्यवहार पर निर्भर करता है; सभी स्टैंड-अलोन printfएस ऐसा नहीं करेंगे।

ध्यान दें कि यह गैर-xargs पद्धति URL की बहुत बड़ी सूची के लिए सिस्टम सीमाओं के विरुद्ध भी टकरा सकती है। अगर यह एक चिंता है तो ARG_MAX और MAX_ARG_STRLEN पर रिसर्च करें।


यह काम करने लगता है, लेकिन यह केवल मुझे एक 125 बाइट HTML फ़ाइल, के नाम वाले फ़ाइल दे रहा है नहीं वास्तविक फ़ाइल की सामग्री।
फिंच

1
ओह समझा। इसमें एक रीडायरेक्ट शामिल था इसलिए मुझे -Lविकल्प जोड़ने की आवश्यकता थी curl
फिंच

4
संकेत के लिए धन्यवाद! Thats मेरे मैक पर काम कर रहा है, लेकिन मैं पाइपलाइन संस्करण पसंद करता हूं cat urls.txt | xargs -n 1 curl -O;-)
ऑर्केचो

@Pio, काफी उचित, यह सब काम करता है, लेकिन आपके पढ़ने की खुशी के लिए, unix.stackexchange.com/questions/16279/…
ghoti

यह बहुत अच्छा काम किया !. हालाँकि मैंने इसे विंडोज़ पर git bash में प्रयोग किया है, और यह \rटेक्स्ट फ़ाइल के पात्रों को पसंद नहीं करता है।
जेम्स मैकडोनेल

34

एक बहुत ही सरल उपाय निम्नलिखित होगा: यदि आपके पास 'file.txt' जैसी फ़ाइल है

url="http://www.google.de"
url="http://www.yahoo.de"
url="http://www.bing.de"

फिर आप कर्ल का उपयोग कर सकते हैं और बस कर सकते हैं

curl -K file.txt

और कर्ल आपके file.txt में निहित सभी Urls को कॉल करेगा!

इसलिए यदि आपका अपने इनपुट-फ़ाइल-प्रारूप पर नियंत्रण है, तो शायद यह आपके लिए सबसे सरल उपाय है!


1
क्या यह HTTP रखने-जीवित का उपयोग करेगा?
विलियम एंट्रीकेन

@FullDecent यह इस तरह से कनेक्शन का पुनः उपयोग करता है
एलन डोमन

14

या आप ऐसा कर सकते हैं:

cat urls.txt | xargs curl -O

-Iजब आप कमांड के बीच में कैट आउटपुट डालना चाहते हैं तो आपको केवल पैरामीटर का उपयोग करना होगा।


1
यह सुनिश्चित नहीं है कि इसे क्यों वोट दिया गया है, लेकिन यह मेरे लिए पूरी तरह से काम करता है, लेकिन इनपुट के लिए एक फ्लैट टेक्स्ट फ़ाइल के बजाय मेरे पास grep का आउटपुट था।
लूट

1
शायद गलत है क्योंकि यह गलत है। -oकर्ल के लिए विकल्प अपने तर्क के रूप में कोई आउटपुट फ़ाइल निर्दिष्ट करता है। अन्य उत्तर सुझाते हैं -O, जो फ़ाइल के दूरस्थ नाम के आधार पर स्थानीय नाम को निर्धारित करने के लिए कर्ल बताता है।
घोटी

8

xargs -P 10 | curl

जीएनयू समानांतर में xargs -Pकई curlप्रक्रियाएं चला सकता है । 10प्रक्रियाओं को चलाने के लिए :

xargs -P 10 -n 1 curl -O < urls.txt

यदि आपकी अधिकतम डाउनलोड गति नहीं हुई है और यदि सर्वर आईपी को थ्रॉटल नहीं करता है, तो यह 10x डाउनलोड की गति बढ़ाएगा, जो कि सबसे सामान्य परिदृश्य है।

बस -Pबहुत अधिक सेट न करें या आपकी RAM अभिभूत हो सकती है।

GNU parallelसमान परिणाम प्राप्त कर सकता है।

उन तरीकों का नकारात्मक पक्ष यह है कि वे सभी फ़ाइलों के लिए एक ही कनेक्शन का उपयोग नहीं करते हैं, जो कि curlयदि आप एक ही बार में एक से अधिक URL पास करते हैं:

curl -O out1.txt http://exmple.com/1 -O out2.txt http://exmple.com/2

जैसा कि /server/199434/how-do-i-make-curl-use-keepalive-from-the-command-line पर उल्लेख किया गया है

शायद दोनों तरीकों के संयोजन से सबसे अच्छा परिणाम मिलेगा? लेकिन मुझे लगता है कि कनेक्शन को जीवित रखने की तुलना में समानांतरकरण अधिक महत्वपूर्ण है।

इसे भी देखें: कर्ल कमांड लाइन उपयोगिता का उपयोग करके समानांतर डाउनलोड


7

यहाँ मैं इसे एक मैक (OSX) पर कैसे करूँ, लेकिन इसे अन्य प्रणालियों पर समान रूप से काम करना चाहिए:

आपको जिस चीज़ की ज़रूरत है वह एक टेक्स्ट फ़ाइल है जिसमें कर्ल के लिए आपके लिंक हैं

इस तरह:

    http://www.site1.com/subdirectory/file1-[01-15].jpg
    http://www.site1.com/subdirectory/file2-[01-15].jpg
    .
    .
    http://www.site1.com/subdirectory/file3287-[01-15].jpg

इस काल्पनिक मामले में, टेक्स्ट फ़ाइल में 3287 लाइनें हैं और प्रत्येक लाइन 15 चित्रों के लिए कोडिंग है।

मान लें कि हम इन लिंक को हमारी हार्ड ड्राइव के शीर्ष स्तर (/) पर testcurl.txt नामक पाठ फ़ाइल में सहेजते हैं।

अब हमें टर्मिनल में जाना है और बैश शेल में निम्नलिखित कमांड दर्ज करना है:

    for i in "`cat /testcurl.txt`" ; do curl -O "$i" ; done

सुनिश्चित करें कि आप वापस टिक का उपयोग कर रहे हैं (`) यह भी सुनिश्चित करें कि झंडा (-O) एक कैपिटल ओ है और शून्य नहीं है

-O ध्वज के साथ, मूल फ़ाइल नाम लिया जाएगा

हैप्पी डाउनलोडिंग!


आपको अपने चर संदर्भों को उद्धृत करना चाहिए। क्या होगा अगर किसी ने आपकी टेक्स्ट फ़ाइल में एक विशेष चरित्र के साथ एक फ़ाइल लगाई है? एक पंक्ति जोड़ें, echo ";sudo rm -rf ~/" >> testcurl.txtऔर देखें कि क्या होता है।
घोटी

4
^ यदि आप नहीं जानते हैं, तो ऐसा न करें।
रिक हैनलन II

2
यह एक भयानक समाधान है; यह न केवल प्रत्येक डाउनलोड के लिए एक अलग प्रक्रिया पैदा करता है, बल्कि इसे हर एक बार टीसीपी कनेक्शन को फिर से स्थापित करना पड़ता है, यहां तक ​​कि मध्यम-विलंबता नेटवर्क पर भी बहुत समय बर्बाद होता है।
cnst 15'15

4

जैसा कि दूसरों ने सही उल्लेख किया है:

-cat urls.txt | xargs -0 curl -O
+cat urls.txt | xargs -n1 curl -O

हालाँकि, यह प्रतिमान एक बहुत बुरा विचार है, खासकर यदि आपके सभी URL एक ही सर्वर से आते हैं - आप न केवल एक और कर्ल आवृत्ति पैदा करने वाले हैं, बल्कि प्रत्येक अनुरोध के लिए एक नया TCP कनेक्शन भी स्थापित करेंगे, जो अब तक सर्वव्यापी के साथ अत्यधिक अक्षम है, और इससे भी अधिक।

कृपया इसके बजाय इसका उपयोग करें:

-cat urls.txt | xargs -n1 curl -O
+cat urls.txt | wget -i/dev/fd/0

या, और भी सरल:

-cat urls.txt | wget -i/dev/fd/0
+wget -i/dev/fd/0 < urls.txt

सबसे सरल अभी तक:

-wget -i/dev/fd/0 < urls.txt
+wget -iurls.txt

2
ओपी विशेष रूप से कर्ल के साथ ऐसा करने के बारे में था। शायद यह एक ऐसी प्रणाली पर उपयोग के लिए है जहां कर्ल पहले से ही स्थापित है, लेकिन उदाहरण के लिए, OSX नहीं है। इसके अलावा, devfs पर निर्भर रहने की कोई आवश्यकता नहीं है, आप स्टड -i-को संदर्भित करने के लिए भी उपयोग कर सकते हैं । Ie: wget -i- < urls.txtअंत में, यदि आप curlएक बार में कई URL का अनुरोध करना चाहते हैं, तो आपको रिस्पांस की आवश्यकता के बिना, आप हमेशा उन्हें केवल कमांड लाइन पर रख सकते हैं। xargs curl < urls.txtयह HTTP / 1.1 का उपयोग करता है। आप कमांड लाइन की लंबाई द्वारा URL की संख्या में सीमित हैं जिसे xargs प्रोसेस कर सकता है। के साथ इस सीमा का पता लगाएं getconf ARG_MAX
गोठी १i
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.