कमांड विकल्पों में एक फ़ाइल के बजाय एक पाइप से पढ़े गए डेटा का उपयोग करना


18

प्रति व्यक्ति परिभाषा, इस कमांड को एक फाइल से इनपुट मिलता है।

$ command -r FILENAME

मान लीजिए कि FILENAMEफ़ाइल नाम की सूची वाली एक फ़ाइल है, जैसा कि इसका उपयोग करके उत्पन्न की गई थी ls > FILENAME

इसके बजाय, मैं lsसीधे परिणाम के साथ कमांड कैसे खिला सकता हूं ? मेरे सिर में ऐसा कुछ संभव होना चाहिए:

$ ls | command -r

लेकिन यह नहीं है, lsएक तर्क के रूप में आउटपुट नहीं मिलता है। आउटपुट:

Usage: command -r FILENAME
error: -r option requires an argument

मैं वांछित प्रभाव कैसे प्राप्त कर सकता हूं?


जवाबों:


32

यह कमांड पर निर्भर है। किसी फ़ाइल से पढ़ने वाले कुछ आदेश यह अपेक्षा करते हैं कि फ़ाइल एक नियमित फ़ाइल हो, जिसका आकार पहले से ज्ञात हो, और जिसे किसी भी स्थिति से पढ़ा जा सकता है और वापस किया जा सकता है। यह संभव नहीं है यदि फ़ाइल की सामग्री फ़ाइल नामों की एक सूची है: तो कमांड संभवतः एक पाइप के साथ सामग्री होगी जिसे वह बस शुरू से अंत तक क्रमिक रूप से पढ़ेगा। एक पाइप के माध्यम से डेटा को फीड करने के कई तरीके हैं जो एक फ़ाइल नाम की अपेक्षा करते हैं।

  • कई कमांड -एक विशेष नाम के रूप में व्यवहार करते हैं , जिसका अर्थ है कि फ़ाइल खोलने के बजाय मानक इनपुट से पढ़ना । यह एक सम्मेलन है, एक दायित्व नहीं है।

    ls | command -r -
  • कई यूनिक्स संस्करण /devमानक डिस्क्रिप्टर को नामित करने में विशेष फाइलें प्रदान करते हैं । यदि /dev/stdinमौजूद है, तो उसे खोलना और उससे पढ़ना मानक इनपुट से पढ़ने के बराबर है; इसी तरह /dev/fd/0अगर यह मौजूद है।

    ls | command -r /dev/stdin
    ls | command -r /dev/fd/0
  • यदि आपका शेल ksh, bash या zsh है, तो आप कुछ फ़ाइल डिस्क्रिप्टर को आवंटित करने के व्यवसाय के साथ शेल डील कर सकते हैं। इस पद्धति का मुख्य लाभ यह है कि यह मानक इनपुट से बंधा हुआ नहीं है, इसलिए आप किसी अन्य चीज़ के लिए मानक इनपुट का उपयोग कर सकते हैं, और आप इसे एक से अधिक बार उपयोग कर सकते हैं।

    command -r <(ls)
  • अगर कमांड को उम्मीद है कि नाम एक विशेष रूप (आमतौर पर एक विशेष एक्सटेंशन) है, तो आप इसे एक प्रतीकात्मक लिंक के साथ मूर्ख बनाने की कोशिश कर सकते हैं।

    ln -s /dev/fd/0 list.foo
    ls | command -r list.foo

    या आप एक नामित पाइप का उपयोग कर सकते हैं।

    mkfifo list.foo
    ls >list.foo &
    command -r list.foo

ध्यान दें कि फ़ाइलों की एक सूची के साथ lsसमस्या उत्पन्न होती है क्योंकि lsफ़ाइल नाम नाम बदलने के लिए जाता है जब वे अनपेक्षित वर्ण होते हैं। printf '%s\n' *अधिक विश्वसनीय है - यह फ़ाइल नामों में शाब्दिक रूप से प्रत्येक बाइट को मुद्रित करेगा। नए नाम वाली फ़ाइल नाम अभी भी परेशानी का कारण बनेंगे, लेकिन यह अपरिहार्य है यदि कमांड नए नामों से अलग फ़ाइल नामों की सूची की उम्मीद करता है।


सभी संभावनाओं की गणना के लिए +1। IMO प्रक्रिया प्रतिस्थापन इस स्थिति के लिए सही उत्तर है।
ग्लेन जैकमैन

7

यह होना चाहिए:

ls | xargs -n 1 command -r

संपादित करें: रिक्त स्थान वाले नामों के लिए:

ls | xargs -d '\n' -n 1 command -r

यह समस्याग्रस्त हो सकता है यदि commandयह विश्वास करता है कि इसमें सभी फ़ाइल नाम हैं जो इसे एक ही बार में कमांड लाइन पर आवश्यकता होगी। Xargs के कुछ संस्करण commandएक समय में कुछ फ़ाइल नाम (10, यह मुझे लगता है) देंगे। लगता है कि GNU xargs सब कुछ एक ही बार में देता है।
ब्रूस एडगर

2

वास्तव में, एकमात्र विश्वसनीय समाधान जो मुझे पता है कि सभी फ़ाइलनामों को संभाल सकता है, जिसमें एक नई रेखा के साथ वे शामिल हैं:

find . -maxdepth 1 -print0 | xargs -n 1 -0 command -r

इस मामले में फ़ाइल नाम में एकमात्र गैर अनुमत चरित्र शून्य वर्ण है, जिसे वैसे भी फ़ाइल नाम में अनुमति नहीं है।


1

कई आदेश -एक "फ़ाइल नाम" के रूप में स्वीकार करते हैं, जिसका अर्थ है "मानक इनपुट का उपयोग करें", लेकिन यह सम्मेलन सार्वभौमिक से बहुत दूर है। मैन पेज पढ़ें।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.