मैं STDIN से एक चर में कई पंक्तियों को कैसे पढ़ूं?


24

मैं इस सवाल का कोई फायदा नहीं हुआ है। मैं काम पर यहाँ एक निर्माण प्रक्रिया को स्वचालित कर रहा हूं, और मैं जो करने की कोशिश कर रहा हूं वह संस्करण संख्या और निर्माण का एक छोटा विवरण है जो बहु-पंक्ति हो सकता है। यह जिस सिस्टम पर चलता है वह OSX 10.6.8 है।

मैंने कैट का उपयोग करने से लेकर प्रत्येक पंक्ति को आवश्यक रूप से संसाधित करने तक सब कुछ देखा है। मैं यह पता नहीं लगा सकता कि मुझे क्या उपयोग करना चाहिए और क्यों।

प्रयास

read -d '' versionNotes

यदि उपयोगकर्ता को बैकस्पेस कुंजी का उपयोग करना है तो गारबल्ड इनपुट में परिणाम। इसके अलावा इनपुट को समाप्त करने का कोई अच्छा तरीका नहीं है क्योंकि ^ D समाप्त नहीं करता है और ^ C बस प्रक्रिया से बाहर निकलता है।

read -d 'END' versionNotes

काम करता है ... लेकिन अगर बैकस्पेस कुंजी की जरूरत है, तब भी इनपुट को पकड़ लेता है।

while read versionNotes
do
  echo "  $versionNotes" >> "source/application.yml"
done

इनपुट को ठीक से समाप्त नहीं करता है (क्योंकि मुझे खाली स्ट्रिंग के विरुद्ध मिलान करने में बहुत देर हो चुकी है)।


आप उपयोगकर्ता से यह जानकारी प्राप्त कर रहे हैं, सही है?
ग्लेन जैकमैन

सही बात; मैं चाहता हूं कि स्क्रिप्ट को निष्पादित करते समय उपयोगकर्ता टर्मिनल में इस जानकारी को दर्ज करें।
रॉबर्ट के

1
आपने खुद को स्पष्ट नहीं किया है, बल्कि मैं कहूंगा।
गरीब

जवाबों:


20

man bash उल्लेख «...

कमांड प्रतिस्थापन $ (कैट फ़ाइल) को समकक्ष लेकिन तेजी से $ (<फ़ाइल) द्वारा प्रतिस्थापित किया जा सकता है।

... »

$ myVar=$(</dev/stdin)
hello
this is test
$ echo $myVar
hello this is test
$ echo "$myVar"
hello
this is test

और मैं मानता हूं कि यह ध्यान देने योग्य है - echo "$myVar"जैसा कि दिया गया था, इनपुट प्रदर्शित किया होगा।


1
मल्टीलाइन इनपुट के बाद कैसे रोकें? अगर मैं Ctrl C दबाता हूं तो यह रुक जाता है लेकिन चर नहीं बचा है!
निखिल

2
UNIX® टर्मिनलों में "अनुशासन" होता है: en.wikipedia.org/wiki/Line_discipline • इसकी जाँच करें कि "ईओफ़" का क्या अर्थ है • क्या पढ़ें man stty, पता करें कि वर्तमान सेटिंग्स कैसे प्राप्त करें
poige

2
ctrl-d को रोकना है।
फ्रीब

9

इसे इस्तेमाल करे:

user@host:~$ read -d '' x <<EOF
> mic
> check
> one
> two
> EOF

बिना लाइन ब्रेक के:

user@host:~$ echo $x
mic check one two

लाइन ब्रेक के साथ :

user@host:~$ echo "$x"
mic
check
one
two

2
-d ''वास्तव में मैं क्या जरूरत है। धन्यवाद
बजे ब्रूनो ब्रोंस्की

@Bruno मेरी खुशी; यह एक मुश्किल है। विशेष रूप से पहली नज़र में, यह काफी मानक दिखता है। एक बार जब आप विभिन्न आइडिओसिंक्रासी की हैंग हो जाते हैं, तो यह काफी उपयोगी हो सकता है।
आवाजें

8

अपने सभी बैश स्क्रिप्टिंग जरूरतों के लिए उत्कृष्ट बैश गाइड का संदर्भ लें ।

विशेष रूप से बैश एफएक्यू में यह नंबर # 1 पर है:

मैं एक फ़ाइल (डेटा स्ट्रीम, चर) लाइन-बाय-लाइन (और / या फ़ील्ड-बाय-फ़ील्ड) कैसे पढ़ सकता हूं?


आप उपयोग करने के लिए कहते हैं read -r, लेकिन मैं इसे STDIN से कैसे प्राप्त करूं? मैंने read -rजल्दी उपयोग करने का प्रयास किया ।
रॉबर्ट के

यह डिफ़ॉल्ट रूप से स्टड से पढ़ता है।
adaptr

2

जब तक मैं एक रिक्त लाइन के साथ नहीं आया, तब तक मैंने प्रत्येक पंक्ति से निपटकर इस समस्या को हल कर दिया है। यह मेरी स्थिति के लिए काफी अच्छा है। लेकिन अगर कोई बेहतर समाधान जोड़ना चाहता है, तो ऐसा करने के लिए स्वतंत्र महसूस करें।

echo "---
notes: |" > 'version.yml'

while read line
do
  # break if the line is empty
  [ -z "$line" ] && break
  echo "  $line" >> "source/application.yml"
done

read -rइसके बजाय उपयोग करें ।
13:25

2

आप विम, पिको जैसे संपादक शुरू कर सकते हैं ...

${VISUAL:-${EDITOR:-vi}} source/application.yml

उम ... कैसे किसी भी तरह से ओपी के सवाल का जवाब देता है?
13:25

वह स्क्रिप्ट से संपादक शुरू कर सकता है।
मिरिके वुटकोविसी

और वह पूरा करता है क्या, वास्तव में? उन्होंने कहा कि पाठ का उपयोग करना चाहता से स्क्रिप्ट में एक फ़ाइल, लिखने जानकारी नहीं करने के लिए एक फ़ाइल।
15

वह उपयोगकर्ता से पाठ पढ़ने और इसे एक फ़ाइल में लिखने के लिए तैयार नहीं था। कृपया प्रश्न से जुड़ी टिप्पणियाँ पढ़ें।
मिर्चे वुटकोविसी 16

1

पहले कुछ सुधार:

  1. लाइन उपयोग पर "संस्करण" की अनुमति देने के लिए -eजो रीडलाइन का उपयोग करता है (ताकि आपके पास बैश इतिहास और सभी संपादन विशेषताएं हों)
  2. -dकेवल एक चरित्र लेता है। उदाहरण के लिए 'END' से 'E' लगता है और जब भी उपयोगकर्ता एक 'E' लिखता है तो पढ़ना बंद हो जाता है (मुझे लगता है कि आप जो चाहते हैं ...)

ऐसा करने के लिए कुछ संभावनाएं हैं। मैं लाइन के द्वारा रीड लाइन के लिए जाऊँगा और खाली लाइन मिलने पर रुक जाऊँगा (हालाँकि आप कोई भी स्टॉप शब्द सेट कर सकते हैं):

unset tmp
while :
do 
 read line
 [[ $line == "" ]] && tmp="${tmp:0:$((${#tmp}-1))}" && break
 tmp="$tmp"$line$'\n'
done

0

आपके पास कई तरीके हैं।

सबसे सरल तरीकों में से एक है:

MYVAR=$(yourcommand)
echo $"MYVAR"

उदाहरण के लिए:

MYVAR=$(ls /)
echo $"MYVAR"

सिवाय मैं एलएस की तरह एक शेल कमांड निष्पादित नहीं कर रहा हूं। मैं उपयोगकर्ता से मल्टी-लाइन इनपुट का अनुरोध कर रहा हूं।
रॉबर्ट के

यह बहुत बुरा अभ्यास है; के उत्पादन की प्रक्रिया नहीं है ls!
एडेप्टर

@adaptr हमने यह सब पहले सुना है, क्या आप एक अच्छा विकल्प सुझाएंगे?
आवाजें

0

हम एक निर्माण का उपयोग कर रहे हैं xargs और ctrl-d को तोड़ने के लिए। मैं इसके साथ पूरी तरह से संतुष्ट नहीं हूं, लेकिन यह निश्चित रूप से मल्टी-लाइन उपयोगकर्ता इनपुट लेने और इसे एक चर (स्वरूपण) में भरने का काम करता है। (पहले और तीसरे असाइनमेंट xargs इनपुट की सामग्री के आसपास उद्धरण जोड़ते हैं।)

    printf "\\033[1mWhen finished hit ctrl-d on a new line to proceed.\\033[0m  \\n\\n" 
    # this will load the user's input into a variable instead of a file 
    reminderBody="\"" 
    reminderBody+=$( xargs -0 ) 
    reminderBody+="\"" 

हम रिमाइंडरबॉडी का उपयोग मेल द्वारा भेजे गए ई-मेल (बैश के माध्यम से) के विषय के रूप में करते हैं।


-1

देखें: http://tldp.org/LDP/abs/html/internal.html#READR

उपयोग करें readऔर ध्यान दें कि यदि आप एक पंक्ति को समाप्त करते हैं \तो नई रेखा को अनदेखा किया जाता है। तो आप कर सकते हैं:

#! / Bin / bash

पढ़ें -p "संस्करण:" संस्करण
गूंज $ संस्करण

# कुछ इनपुट दर्ज करें और "" के साथ लंबी लाइनें समाप्त करें, फिर अंत में सादा प्रवेश करें
read -p "विवरण:" विवरण
इको-ई "$ संस्करण \ n $ विवरण >> yourfile.txt

अगर मैं सिर्फ रेखा विराम के साथ एक पैराग्राफ को अनदेखा करना चाहता था, हाँ। लेकिन जैसा कि यह एक निर्माण स्क्रिप्ट के लिए जारी नोटों की एक उत्पन्न सूची है, मुझे उन पंक्ति विरामों को संरक्षित करने में सक्षम होने की आवश्यकता है; मैं उदाहरण के लिए, बुलेटेड सूची में प्रवेश करने का प्रयास कर सकता हूं।
रॉबर्ट के

एबीएस भयावह अनुपात का एक राक्षसी है। इसका 90% हिस्सा गलत है।
13:25

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