बैश: कमांड के आउटपुट से एक बार में एक लाइन कैसे पढ़ें?


49

मैं bash में कमांड के आउटपुट को पढ़ने की कोशिश कर रहा हूं while loop

while read -r line
do
    echo "$line"
done <<< $(find . -type f)

मुझे जो आउटपुट मिला है

ranveer@ranveer:~/tmp$ bash test.sh
./test.py ./test1.py ./out1 ./test.sh ./out ./out2 ./hello
ranveer@ranveer:~/tmp$ 

इसके बाद मैंने कोशिश की

$(find . -type f) | 
while read -r line
do
    echo "$line"
done 

लेकिन इसने एक त्रुटि उत्पन्न की test.sh: line 5: ./test.py: Permission denied

तो, मैं इसे लाइन से लाइन कैसे पढ़ता हूं क्योंकि मुझे लगता है कि वर्तमान में यह एक ही बार में पूरी लाइन को खिसका रहा है।

आवश्यक उत्पादन:

./test.py
./test1.py
./out1
./test.sh
./out
./out2
./hello

3
मेरा सुझाव है कि बैश एफएक्यू 01 पढ़ें - बचने के लिए जाल के बारे में बहुत सारी उपयोगी जानकारी और सलाह।
jw013

के लिए while readहिस्सा है, को देखने के आईएफएस को समझना और सवाल वहाँ से जोड़ा।
गिल्स एसओ- बुराई को रोकें '

जवाबों:


54

एक गलती है, आपको जरूरत < <(command)नहीं है<<<$(command)

< <( )एक प्रक्रिया प्रतिस्थापन है , $()एक कमांड प्रतिस्थापन है और यहां<<< एक स्ट्रिंग है


2
@RRRag $( )सब कुछ के आसपास रखने की कोशिश कर बंद करो ! यह कमांड प्रतिस्थापन के लिए वाक्यविन्यास है , जो कमांड आउटपुट का उपयोग करने का केवल एक तरीका है। पाइप और प्रक्रिया प्रतिस्थापन और यहां-स्ट्रिंग अन्य हैं, और वे सभी अलग-अलग वाक्यविन्यास हैं, स्वाभाविक रूप से। जब तक आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं, आपको किसी भी तरह से फ़ाइल नाम को पार्स नहीं करना चाहिए।
jw013

धन्यवाद, इसके बारे में और काम करेंगे Process Substitution
रणराग

@ jw013: मैं बैश शुरुआती हूं। भविष्य में आपके सुझाव को मेरे दिमाग में रखेंगे।
रणराग

13

ध्यान दें कि न्यूलाइन वर्णों से फ़ाइल नाम को रोकना कुछ भी नहीं है। प्रत्येक फ़ाइल के लिए एक कमांड को चलाने के लिए विहित रास्ता मिल गया खोजने के द्वारा होता है।

find . -type f -exec cmd {} \;

और अगर आप चाहते हैं कि चीजें बेश में की जाएं:

find . -type f -exec bash -c '
  for file do
    something with "$file"
  done' bash {} +

इसके अलावा, स्क्रिप्ट में "रीड" कमांड को कॉल करने का विहित तरीका (यदि आप नहीं चाहते कि यह इनपुट पर अतिरिक्त प्रोसेसिंग करे):

IFS= read -r var

-rreadविशेष रूप से बैकस्लैश कैरेक्टर (सेपरेटर्स और न्यूलाइन के लिए एक एस्केप कैरेक्टर के रूप में) को रोकने के लिए है, और आईएफएस = के लिए सेपरेटर की लिस्ट को सेट करने के लिए खाली स्ट्रिंग read(अन्यथा यदि कोई व्हाट्सएप कैरेक्टर उस लिस्ट में था, तो उनसे छीन लिया जाएगा) इनपुट की शुरुआत और अंत)।

गोले में छोरों का उपयोग करना आमतौर पर एक बुरा विचार है (न कि चीजों को गोले में कैसे किया जाता है जहां आप कई उपकरण काम करते हैं सामूहिक और समवर्ती एक क्रम में एक या अधिक उपकरण चलाने के बजाय सैकड़ों बार काम करते हैं)।

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