फ़ाइल नाम के बिना एक बैश चर में दी गई फ़ाइल की पंक्तियों की संख्या को बैश करें


79

मेरे पास बैश स्क्रिप्ट में तीन निर्माण हैं:

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE)
echo $NUMOFLINES" lines"

echo $(wc -l $JAVA_TAGS_FILE)" lines"

echo "$(wc -l $JAVA_TAGS_FILE) lines"

और वे दोनों समान आउटपुट तब उत्पन्न करते हैं जब स्क्रिप्ट चलती है:

121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines

यानी फ़ाइल का नाम भी प्रतिध्वनित होता है (जो मैं नहीं चाहता)। ये स्क्रिफ़ल क्यों विफल हो जाते हैं और मुझे एक साफ उत्पादन कैसे करना चाहिए:

121711 lines

?


जवाबों:


157

अपने खुद के डेटा का उपयोग कर एक उदाहरण

आप JUMA_TAGS_FILE से पुनर्निर्देशन का उपयोग करके NUMOFLINES चर में अपने फ़ाइलनाम को एम्बेड करने से बच सकते हैं , बल्कि फ़ाइल नाम को wc के तर्क के रूप में पारित करने के बजाय । उदाहरण के लिए:

NUMOFLINES=$(wc -l < "$JAVA_TAGS_FILE")

स्पष्टीकरण: आउटपुट में फ़ाइलनाम से बचने के लिए पाइप या पुनर्निर्देशन का उपयोग करें

WC उपयोगिता इसके उत्पादन में फ़ाइल का नाम मुद्रित नहीं होगा यदि इनपुट एक पाइप या पुनर्निर्देशन ऑपरेटर से लिया जाता है। इन विभिन्न उदाहरणों पर विचार करें:

# wc shows filename when the file is an argument
$ wc -l /etc/passwd
41 /etc/passwd

# filename is ignored when piped in on standard input
$ cat /etc/passwd | wc -l
41

# unusual redirection, but wc still ignores the filename
$ < /etc/passwd wc -l
41

# typical redirection, taking standard input from a file
$ wc -l < /etc/passwd
41

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


1
सावधान रहें कि यदि अंतिम पंक्ति लाइन वर्ण के अंत तक समाप्त नहीं होती है तो इस दृष्टिकोण में अंतिम पंक्ति शामिल नहीं होगी। मेरा फिक्स नीचे देखें।
लिंग

15

wc यदि आप इसे एक नहीं देते हैं तो आपको नाम नहीं मिल सकता है।

wc -l < "$JAVA_TAGS_FILE"

2
खैर, फिर नहीं। wcउत्तर में दिखाए गए अनुसार फाइल को पास करें । तो cat "$JAVA_TAGS_FILE" | wc -lया, समतुल्य रूप, wc -l < "$JAVA_TAGS_FILE"। इस तरह, wcकेवल कच्चा डेटा मिलता है, फ़ाइल नाम नहीं।
विटिको


5

(मैक पर लागू करें, और शायद अन्य यूनिक्स)

वास्तव में wc दृष्टिकोण के साथ एक समस्या है: यह अंतिम पंक्ति की गणना नहीं करता है यदि यह रेखा प्रतीक के अंत के साथ समाप्त नहीं होती है।

इसकी जगह इसका इस्तेमाल करें

nbLines=$(cat -n file.txt | tail -n 1 | cut -f1 | xargs)

या इससे भी बेहतर (धन्यवाद gniourf_gniourf):

nblines=$(grep -c '' file.txt)

नोट: chilicuil द्वारा awk दृष्टिकोण भी काम करता है।


2
बहुत जटिल विधि! शायद आप nblines=$(grep -c '' file)इसके बजाय चाहते हैं (जो इस मामले में अधूरी रेखाओं को गिनने का विहित तरीका है)। ध्यान दें कि हालांकि, POSIX के अनुसार, आप अधूरी रेखाएं (और लाइनें नहीं ) गिन रहे हैं । आप वास्तव में एक बाइनरी फ़ाइल के साथ काम कर रहे हैं, न कि एक टेक्स्ट फ़ाइल के साथ
गनीउर_गनीउरफ

@gniourf_gniourf धन्यवाद, मुझे इस बारे में नहीं पता था, यह बहुत अच्छा काम करता है और इससे भी अधिक संक्षिप्त है।
ling

यह शायद बेहतर समाधानnblines=$(($(cat "file.txt" | wc -l) + 1))
एंड्री इज़मैन

3

यह बहुत आसान है:

NUMOFLINES=$(cat $JAVA_TAGS_FILE | wc -l )

या

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE | awk '{print $1}')

पहला बेकार बिल्ली का उपयोग है।
kap

@kap नहीं, यह केवल इस तरह दिखता है। यदि आप से छुटकारा पा लेते हैं cat, तो आपके पास 2 उदाहरण होगा, क्योंकि wc -l2 कॉलम लौटाता है जब इसे केवल फ़ाइल के साथ उपयोग किया जा रहा है।
स्लावा सेमुशिन

-3

मैं आमतौर पर बैश के 'बैक टिक' फीचर का इस्तेमाल करता हूं

export NUM_LINES=`wc -l filename`

ध्यान दें कि 'टिक' 'बैक टिक' है, उदाहरण के लिए 'सामान्य सिंगल कोट' नहीं


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