स्रोत कोड के भीतर पढ़ने -p के संकेत में एक लंबी स्ट्रिंग को कई लाइनों में कैसे तोड़ना है?


19

मैं एक इंस्टॉलेशन स्क्रिप्ट लिख रहा हूं जिसे इस प्रकार चलाया जाएगा /bin/sh

फ़ाइल के लिए एक लाइन प्रॉम्प्टिंग है:

read -p "goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n] " REPLY

मैं इस लंबी लाइन को कई लाइनों में तोड़ना चाहूंगा ताकि उनमें से कोई भी 80 अक्षर से अधिक न हो। मैं स्क्रिप्ट के स्रोत कोड के भीतर लाइनों के बारे में बात कर रहा हूं ; स्क्रिप्ट निष्पादित होने पर स्क्रीन पर मुद्रित होने वाली लाइनों के बारे में नहीं !

मैंने क्या कोशिश की है:

  • मुट्ठी दृष्टिकोण:

    read -p "goat can try change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] " REPLY

    यह काम नहीं करता है क्योंकि यह प्रिंट नहीं करता है Would you like to add this feature? [Y|n]

  • दूसरा तरीका:

    echo "goat can try change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] "
    read REPLY

    के रूप में अच्छी तरह से काम नहीं करता है। यह प्रॉम्प्ट के बाद एक नई लाइन प्रिंट करता है। मदद -nकरने के लिए विकल्प जोड़ना echo: यह सिर्फ प्रिंट करता है:

    -n goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n]
    # empty line here
  • मेरा वर्तमान वर्कअराउंड है

    printf '%s %s ' \
        "goat can try change directory if cd fails to do so." \
        "Would you like to add this feature? [Y|n] "
    read REPLY

और मुझे आश्चर्य है कि क्या कोई बेहतर तरीका है।

याद रखें कि मैं एक /bin/shसुसंगत समाधान की तलाश में हूं ।


1
मेरा सुझाव है कि आप 1. एक व्यापक टर्मिनल और / या संपादक विंडो का उपयोग करें (जैसे मैं अपने 1440p मॉनिटर पर 51 लाइन टर्मिनल द्वारा एक 192 कॉलम का उपयोग करता हूं - लॉग फ़ाइलों और पूंछ के स्रोत कोड को संपादित करने के लिए महान) और 2. स्वीकार करना सीखें। तथ्य यह है कि कभी-कभी स्रोत कोड लाइनें 80 वर्णों से अधिक लंबी होंगी - यह अपरिहार्य है। यदि मैंने एक छोटे से फ़ॉन्ट का उपयोग किया है, तो मेरे पास एक भी व्यापक टर्मिनल हो सकता है लेकिन मेरी वर्तमान स्थापना चौड़ाई और सुगमता के बीच एक अच्छा समझौता है।
कैस

जवाबों:


17

सबसे पहले, चलो एक चर का उपयोग करके पाठ लाइन से पढ़ने को कम करते हैं:

text="line-1 line-2"             ### Just an example.
read -p "$text" REPLY

इस तरह समस्या यह हो जाती है: एक चर के लिए दो लाइनें कैसे असाइन करें।

बेशक, ऐसा करने का पहला प्रयास है:

a="line-1 \
line-2"

जैसा कि लिखा गया है, aवास्तव में var को मूल्य मिलता है line-1 line-2

लेकिन आप इंडेंटेशन की कमी को पसंद नहीं करते हैं जो यह बनाता है, अच्छी तरह से, फिर हम यहां-डॉक से वेरिए में लाइनों को पढ़ने की कोशिश कर सकते हैं (ध्यान रखें कि यहां-डॉक के अंदर इंडेंटेड लाइनों को टैब की जरूरत है, स्पेस नहीं, सही ढंग से काम करने के लिए):

    a="$(cat <<-_set_a_variable_
        line-1
        line-2
        _set_a_variable_
    )"
echo "test1 <$a>"

लेकिन यह विफल हो जाएगा क्योंकि वास्तव में दो लाइनें लिखी गई हैं $a। केवल एक लाइन प्राप्त करने के लिए वर्कअराउंड हो सकता है:

    a="$( echo $(cat <<-_set_a_variable_
        line 1
        line 2
        _set_a_variable_
        ) )"
echo "test2 <$a>"

यह करीब है, लेकिन अन्य अतिरिक्त मुद्दों को बनाता है।

सही समाधान।

ऊपर दिए गए सभी प्रयास इस समस्या को और अधिक जटिल बना देंगे कि इसे करने की आवश्यकता है।

एक बहुत ही बुनियादी और सरल तरीका है:

a="line-1"
a="$a line-2"
read -p "$a" REPLY

आपके विशिष्ट उदाहरण के लिए कोड (किसी भी शेल के लिए जिसका readसमर्थन करता है -p):

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        read -p "$a" REPLY

अन्य सभी गोले के लिए, उपयोग करें:

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        printf '%s' "$a"; read REPLY

@BinaryZebra मुझे पता है। मैंने सिर्फ "किसी भी शेल के लिए" सही किया क्योंकि सभी गोले पढ़े नहीं हैं और उन सभी को नहीं है जिनके पास -p है।
terdon

@terdon हम दोनों समझौते में हैं धन्यवाद का कारण :-)। एक बार फिर धन्यवाद।

1

लाइनों के अंत में बैकस्लैश कई लाइनों पर कमांड को जारी रखने की अनुमति देता है, आउटपुट में वास्तविक लाइन टूटता नहीं है।

इसलिए आपका पहला दृष्टिकोण, उदाहरण के लिए, कमांड बन जाता है

read -p "goat can try change directory if cd fails to do so. " "Would you like to add this feature? [Y|n] " REPLY

मुझे यकीन नहीं है कि आप कई लाइनों का आउटपुट क्यों पढ़ना चाहते हैं, लेकिन मैं बस readप्रॉम्प्ट लाइन और echoपूर्ववर्ती लाइन (एस) के लिए उपयोग करूंगा ।

कई लाइनों पर कोड को अधिक पठनीय बनाने के लिए, लाइनों के बीच अपने उद्धरणों को बंद / खोलें नहीं।

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

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY

मैं नहीं चाहता कि यह दो लाइनें छपे! मैं सिर्फ स्क्रिप्ट के स्रोत कोड में प्रति पंक्ति 80 वर्णों में फिट होना चाहता हूं ! हालांकि उत्तर के लिए धन्यवाद :)
Mateusz Piotrowski

मुझे आपके द्वारा सुझाए गए दृष्टिकोण पसंद नहीं है क्योंकि कोई इंडेंटेशन नहीं है। अगर readकिसी फ़ंक्शन के भीतर मेरा इंडेंट है, तो आपका दृष्टिकोण पठनीयता को गड़बड़ा देता है।
माटुस्स पिओत्रोस्की

1

मैं बाइनरीज़ेब्रा के दृष्टिकोण को क्लीनर होने के लिए एक चर का उपयोग कर पाता हूं , लेकिन आप इसे वैसे भी कर सकते हैं जैसे आप प्रयास कर रहे थे। आपको बस उद्धरणों के अंदर लाइन ब्रेक रखने की आवश्यकता है:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY

क्या आपको लगता है कि हर लाइन के बाद नई सुर्खियाँ जोड़ने से पठनीयता बढ़ेगी? क्योंकि मैं \nअपने संकेत में सम्मिलित करने के लिए रास्ता नहीं तलाश रहा था । मैं सिर्फ कोड को कई लाइनों में तोड़ना चाहता था ताकि हर पंक्ति अधिकतम 80 वर्णों की हो।
मट्टुसज़ पियोत्रोस्की

1
@ माटेउसज़पॉट्रोस्की ओह, यह बहुत अधिक समझ में आता है। तब मेरा जवाब बहुत उपयोगी नहीं है। कृपया अपना प्रश्न संपादित करें और स्पष्ट करें कि आप कोड को विभाजित करना चाहते हैं न कि आउटपुट को। मैं अभी मोबाइल पर हूं लेकिन मैं देखूंगा कि क्या मैं कल कुछ लेकर आ सकता हूं।
terdon

1
@MateuszPiotrowski किया, मैंने मूल रूप से जो आप कोशिश कर रहे थे उसका एक कार्यशील संस्करण जोड़ा।
terdon

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