2011-08-19 11 views
19

मैं चर के रूप में 'wc' से आने वाली रेखाओं का उपयोग करना चाहता हूं। उदाहरण के लिए:चर के रूप में wc के परिणाम

echo 'foo bar' > file.txt 
echo 'blah blah blah' >> file.txt 
wc file.txt 

2 5 23 file.txt 

मैं $lines, $words और $characters मूल्यों 2, 5 से जुड़े, और 23 की तरह कुछ करना चाहते हैं। मैं बैश में ऐसा कैसे कर सकता हूं?

उत्तर

7

अन्य समाधान कर रहे हैं, लेकिन एक साधारण एक है जो मैं आमतौर पर उपयोग करने में wc के उत्पादन में डाल करने के लिए है एक अस्थायी फ़ाइल, और फिर वहां से पढ़ें:

wc file.txt > xxx 
read lines words characters filename < xxx 
echo "lines=$lines words=$words characters=$characters filename=$filename" 
lines=2 words=5 characters=23 filename=file.txt 

का लाभ यह विधि यह है कि आपको प्रत्येक चर के लिए कई awk प्रक्रियाएं बनाने की आवश्यकता नहीं है। नुकसान यह है कि आपको एक अस्थायी फ़ाइल की आवश्यकता है, जिसे आपको बाद में हटा देना चाहिए।

सावधान रहें: यह काम नहीं करता है:

wc file.txt | read lines words characters filename 

समस्या किसी अन्य प्रक्रिया बनाता है, और चर वहाँ अपडेट किया जाता है read है कि पाइपिंग है, तो वे फोन करने खोल में सुलभ नहीं हैं।

संपादित करें: arnaud576875 द्वारा समाधान जोड़ने:

एक फ़ाइल के लिए लिख बिना
read lines words chars filename <<< $(wc x) 

काम करता है (और पाइप समस्या नहीं है)। यह विशिष्ट विशिष्ट है।

बैश मैनुअल से:

Here Strings 

    A variant of here documents, the format is: 

      <<<word 

    The word is expanded and supplied to the command on its standard input. 

कुंजी "शब्द का विस्तार होता है" बिट है।

set -- `wc file.txt` 
chars=$1 
words=$2 
lines=$3 

यह स्पष्ट रूप से $* और संबंधित चर clobbers -

+0

मेरा से बेहतर लेकिन आपको फ़ाइल 'xxx' या फ़ाइल नाम की आवश्यकता नहीं है:' wc

+0

@ एड्रियन: ऊपर मेरी टिप्पणी देखें: पाइपिंग किसी अन्य प्रक्रिया में चर बनाता है, इसलिए वे कॉलिंग खोल में उपलब्ध नहीं हैं। – dangonfast

+5

'लाइनों को पढ़ना शब्द शब्द <<< $ (wc x) 'फ़ाइल में लिखने के बिना काम करता है (और पाइप समस्या नहीं है) – arnaud576875

3
lines=`wc file.txt | awk '{print $1}'` 
words=`wc file.txt | awk '{print $2}'` 
... 

आप भी wc परिणाम कहीं पहले स्टोर कर सकते हैं .. और फिर इसे पार्स .. यदि आप प्रदर्शन :) बारे में चयन कर रहे हैं

0

आप एक उप खोल खोलने के द्वारा एक चर करने के लिए उत्पादन प्रदान कर सकते हैं:

$ x=$(wc some-file) 
$ echo $x 
1 6 60 some-file 

अब, क्रम अलग-अलग वैरिएबल प्राप्त करने के लिए, सबसे आसान विकल्प का उपयोग करने के लिए है awk:

$ x=$(wc some-file | awk '{print $1}') 
$ echo $x 
1 
,210
30

शुद्ध बैश में: (कोई awk)

a=($(wc file.txt)) 
lines=${a[0]} 
words=${a[1]} 
chars=${a[2]} 

यह बैश की सरणियों का उपयोग करके काम करता है। a=(1 2 3) तत्व 1, 2 और 3 के साथ एक सरणी बनाता है। फिर हम ${a[indice]} वाक्यविन्यास के साथ अलग-अलग तत्वों तक पहुंच सकते हैं।

वैकल्पिक: (gonvaled समाधान के आधार पर)

read lines words chars <<< $(wc x) 

या श में:

a=$(wc file.txt) 
lines=$(echo $a|cut -d' ' -f1) 
words=$(echo $a|cut -d' ' -f2) 
chars=$(echo $a|cut -d' ' -f3) 
+0

क्या आप समझा सकते हैं कि यह क्यों काम करता है? विशेष रूप से, पहली पंक्ति के आसपास अतिरिक्त कोष्ठक क्या करते हैं? उनके बिना, यह अब काम नहीं करता है इसलिए वे बहुत महत्वपूर्ण लगते हैं। –

+0

बाश में, बाहरी '(...) 'एक सरणी बनाएं जो बाद की रेखा सूचकांक। अन्यथा परिणाम केवल तीन संख्याओं की एक सिंगल स्ट्रिंग है –

+0

इस मामले में, कोष्ठक $ (_ command_) कमांड प्रतिस्थापन वाक्यविन्यास का हिस्सा हैं; यह \ 'आदेश \' के समतुल्य है, लेकिन कोष्ठक नोटेशन घोंसले को सरल बनाता है। _command_ को सबहेल में चलाया जाता है, और कमांड प्रतिस्थापन का पाठ _command_ के आउटपुट द्वारा प्रतिस्थापित किया जाता है, जैसा कि आपने इसे टाइप किया था। –

0
declare -a result 
result=($(wc < file.txt)) 
lines=${result[0]} 
words=${result[1]} 
characters=${result[2]} 
echo "Lines: $lines, Words: $words, Characters: $characters" 
4

बस एक और संस्करण जोड़ने के लिए। यहां कुछ अन्य समाधानों के विपरीत, यह अन्य बोर्न शैल के लिए पोर्टेबल है।

संबंधित मुद्दे