दो अलग-अलग कमांडों से एकल कमांड में विलय और पाइप परिणाम कैसे?


35

मैं दो अलग-अलग कमांड से मर्ज (यूनियन) आउटपुट चाहता हूं, और उन्हें एक ही कमांड पर पाइप करता हूं।

एक मूर्खतापूर्ण उदाहरण:

कमांड जो मैं आउटपुट को मर्ज करना चाहता हूं:

cat wordlist.txt
ls ~/folder/*

में:

wc -l

इस उदाहरण में, अगर wordlist.txt में 5 लाइनें और 3 फाइलें हैं, तो मैं wc -l8 वापस करना चाहता हूं ।

$cat wordlist.txt *[magical union thing]* ls ~/folder/* | wc -l
8

मैं उसको कैसे करू?

जवाबों:


56

आपकी जादुई यूनियन चीज़ अर्धविराम है ... और घुंघराले ब्रेसिज़:

    { cat wordlist.txt ; ls ~/folder/* ; } | wc -l

घुंघराले ब्रेसिज़ केवल कमांड को एक साथ समूहीकृत कर रहे हैं, ताकि पाइप का संकेत |संयुक्त आउटपुट को प्रभावित करे।

आप ()एक कमांड समूह के चारों ओर कोष्ठक का भी उपयोग कर सकते हैं , जो एक सब-कमांड में कमांड निष्पादित करेगा। यह घुंघराले ब्रेस के साथ मतभेदों का एक सूक्ष्म सेट है, उदाहरण के लिए निम्नलिखित प्रयास करें:

    cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
    cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd

आप देखेंगे कि वर्तमान कार्यशील निर्देशिका सहित सभी पर्यावरण चर, कोष्ठक समूह से बाहर निकलने के बाद रीसेट हो जाते हैं, लेकिन कर्ली-ब्रेस समूह से बाहर निकलने के बाद नहीं।

अर्धविराम के लिए, विकल्पों में संकेत &&और ||संकेत शामिल हैं, जो सशर्त रूप से दूसरे आदेश को निष्पादित करेंगे, यदि पहला सफल है या यदि नहीं, क्रमशः, जैसे।

    cd $HOME/project && make
    ls $HOME/project || echo "Directory not found."

1
वह काम करता है! मुझे सीखने में मदद करें - यहाँ वास्तव में घुंघराले ब्रेस क्या कर रहे हैं? उनके पास और कौन सी जादुई शक्तियां हैं?
डेविड वनिल

@DavidOneill { list; }एक कंपाउंड कमांड है । से bash(1): सूची को केवल वर्तमान शेल वातावरण में निष्पादित किया जाता है। सूची को एक नई पंक्ति या अर्धविराम के साथ समाप्त किया जाना चाहिए। [..] वापसी की स्थिति सूची की निकास स्थिति है।
लेकेन्स्टाइन

मैंने उत्तर के लिए थोड़ा और जानकारी जोड़ी है। बैश के साथ शेल स्क्रिप्टिंग के लिए निश्चित गाइड है बैश मैनपेज, man bashकमांड लाइन से टाइप करें और इसे ब्राउज़ करें।
पल्बोम्मे

चाहिए; यदि फ़ाइल wordlist.txt मौजूद नहीं है, तो उन आदेशों में && नहीं हो सकता है?
रिनविंड

यदि wordlist.txtकोई त्रुटि मौजूद नहीं है cat, तो मानक त्रुटि पर दिखाई देगा, लेकिन मानक आउटपुट पर नहीं, इसलिए wc -lइससे कोई भी रेखा नहीं गिनेगी। वही ~/folderमौजूद नहीं है। इनमें से 2> /dev/nullप्रत्येक कमांड और उनके अर्धविराम के बीच मानक त्रुटि पर शोर को रोकने के लिए जोड़ सकता है , लेकिन बदसूरत होने के अलावा, त्रुटि संदेश लाइनों की गणना के उद्देश्य के लिए हानिरहित हैं।
पल्बोम्मे

8

चूंकि wcइनपुट के रूप में एक फ़ाइल पथ स्वीकार करता है, आप प्रक्रिया प्रतिस्थापन का उपयोग भी कर सकते हैं:

wc -l <(cat wordlist.txt; ls ~/folder/*)

यह लगभग बराबर:

echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp

मन जो ls ~/folder/*उपनिर्देशिकाओं की सामग्री को लौटाता है यदि कोई है (ग्लोब विस्तार के कारण)। यदि आप अभी सामग्री की सूची बनाना चाहते हैं ~/folder, तो उपयोग करें ls ~/folder


यह wc -lसिर्फ एक बना हुआ उदाहरण था, मैं वास्तव में इसे कुछ अधिक जटिल में पाइप कर रहा हूं जिसमें यह विकल्प नहीं है।
डेविड वनिल

2
@DavidOneill खैर, जैसा कि catएक फ़ाइल तर्क स्वीकार करता है, आप उपयोग कर सकते हैं cat <(cat wordlist.txt; ls wordlist.txt) | wc -lऔर यहां तक ​​कि cat wordlist.txt <(ls wordlist.txt) | wc -l। यह बेशक बहुत बदसूरत है, लेकिन यह कमांड लाइन टूल के साथ अंतहीन संभावनाओं को प्रदर्शित करता है।
लेकेन्स्टाइन

1
@DavidOneill सही, मैंने इसे अब ठीक कर दिया है, धन्यवाद।
लेकेनस्टाइन

1
आप ls ~/folder/ऐसा चाहते हैं कि यदि ~/folderकोई प्रतीकात्मक लिंक लिंक के lsबजाय अपने लक्ष्य की सामग्री को सूचीबद्ध करता है। वैसे, सभी lsआदेशों का पालन किया जाना चाहिए -1ताकि प्रति पंक्ति एक एकल फ़ाइल मुद्रित हो और wc -lफाइलों की गणना का एक वैध तरीका हो।
पेलोम्मे

@pablomme आप सिम्लिंक चीज़ के बारे में सच हैं, लेकिन -1यह निहित है क्योंकि आउटपुट टर्मिनल नहीं बल्कि एक पाइप है।
लेकेनस्टाइन

2

मैं अपने आप से एक ही सवाल पूछ रहा था, और एक छोटी स्क्रिप्ट लिखना समाप्त कर दिया।

magicalUnionThing(मैं इसे कॉल करता हूं append):

#!/bin/sh
cat /dev/stdin
$*

उस स्क्रिप्ट को अमल में लाएं

chmod +x ./magicalUnionThing

अब आप करो

cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l

यह क्या करता है:

  • मानक आउटपुट के लिए मानक इनपुट भेजें
  • तर्क वितर्क करना। $*एक स्ट्रिंग के रूप में सभी तर्क देता है। उस आदेश का आउटपुट डिफ़ॉल्ट रूप से स्क्रिप्ट मानक आउटपुट पर जाता है।

तो मैजिकयोनियनहिंगड का स्टडआउट, तर्क के रूप में पारित आदेश की अपनी स्टड + स्टडआउट होगा।

अन्य उत्तरों के अनुसार निश्चित रूप से सरल तरीके हैं।
शायद यह विकल्प कुछ मामलों में उपयोगी हो सकता है।

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