জটিল একটি বহু-লাইন স্ট্রিং একটি ভেরিয়েবল লিখতে পরিষ্কার উপায়


109

বাশ স্ক্রিপ্টের ভিতরে আমার একটি ভেরিয়েবলের জন্য কিছু জটিল এক্সএমএল লিখতে হবে। এক্সএমএলটিকে বাশ স্ক্রিপ্টের ভিতরে পঠনযোগ্য হওয়া দরকার কারণ এটি যেখানে এক্সএমএল খণ্ডটি বাস করবে, এটি অন্য ফাইল বা উত্স থেকে পড়া হচ্ছে না।

সুতরাং আমার প্রশ্নটি হ'ল যদি আমার একটি দীর্ঘ স্ট্রিং থাকে যা আমি আমার বাশ স্ক্রিপ্টের ভিতরে মানব পাঠযোগ্য হতে চাই এটি সম্পর্কে সবচেয়ে ভাল উপায় কী?

আদর্শভাবে আমি চাই:

  • কোনও চরিত্রের পালাতে হবে না
  • এটি একাধিক লাইন অতিক্রম করে এটি মানব পাঠযোগ্য
  • এটি ইন্ডেন্টেশন রাখুন

এটি কি ইওএফ বা কিছু দিয়ে করা যায়, কেউ কি আমাকে উদাহরণ দিতে পারে?

যেমন

String = <<EOF
 <?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
EOF

আমি বাজি রাখতে ইচ্ছুক যে আপনি কেবল সেই তথ্যটি আবার একটি স্ট্রিমের মধ্যে ফেলে দেবেন। আপনি যখন জিনিসগুলিকে আরও জটিল করে তুলতে এবং স্ট্রিম ব্যবহার করতে পারেন তখন কেন এটি একটি পরিবর্তনশীলতে সঞ্চয় করবেন?
জেনেক্সার

উত্তর:


140

এটি উদ্ধৃতিগুলি এড়ানোর প্রয়োজন ছাড়াই আপনার পাঠ্যটিকে আপনার পরিবর্তনশীলে রাখবে। এটি ভারসাম্যহীন উদ্ধৃতি (অ্যাস্টোস্ট্রোফস, অর্থাত ') পরিচালনা করবে। সেন্ডিনেল (ইওএফ) এর চারপাশে উদ্ধৃতি স্থাপন পাঠ্য প্যারামিটার সম্প্রসারণ থেকে পাঠ্যকে বাধা দেয়। -d''কারণ এটা একাধিক লাইনের (নতুন লাইন এড়িয়ে যান) পড়তে। readএটি একটি অন্তর্নির্মিত বাশ যা এর জন্য কোনও বাহ্যিক কমান্ড কল করার প্রয়োজন হয় না cat

IFS='' read -r -d '' String <<"EOF"
<?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
EOF

17
এড়ানোর জন্য +1 cat
জেমস স্নেরিঞ্জার

4
catএটি একটি বাহ্যিক আদেশ। এটি ব্যবহার না করে তা করে সাশ্রয় হয়। এছাড়াও, কারও কারও মনে দর্শন আছে যে আপনি যদি বিড়ালকে দুটিরও কম যুক্তির সাথে "উর ডাইন 'এটি ভুল" ব্যবহার করেন (যা "অব্যর্থ ব্যবহারের" থেকে পৃথক cat) ব্যবহার করছেন ।
ডেনিস উইলিয়ামসন

9
এবং কখনও কখনও দ্বিতীয়
ইওএফ্ট

9
আমি উপরের বিবৃতিটি ব্যবহার করার চেষ্টা করেছি set -e। মনে হয় readসর্বদা শূন্য নয় returns আপনি পুরু ব্যবহার করে এই আচরণ! read -d .......
krissi

11
এবং যদি আপনি এই Stringফাইলটিতে লেখার জন্য এই বহু-লাইন ভেরিয়েবলটি ব্যবহার করে থাকেন তবে ভেরিয়েবলটিকে "কোয়েটস" এর মতো echo "${String}" > /tmp/multiline_file.txtবা এর মতো করে রাখুন echo "${String}" | tee /tmp/multiline_file.txt। এটি খুঁজতে আমাকে এক ঘন্টারও বেশি সময় নিয়েছে।
আদিত্য

28

আপনি প্রায় সেখানে ছিল। হয় আপনি আপনার স্ট্রিংয়ের সমাবেশের জন্য বিড়াল ব্যবহার করেন বা আপনি পুরো স্ট্রিংটি উদ্ধৃত করেন (এক্ষেত্রে আপনাকে আপনার স্ট্রিংয়ের ভিতরে থাকা উদ্ধৃতিগুলি থেকে বাঁচতে হবে):

#!/bin/sh
VAR1=$(cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
  <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's "Foligno" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
)

VAR2="<?xml version=\"1.0\" encoding='UTF-8'?>
<painting>
  <img src=\"madonna.jpg\" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's \"Foligno\" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>"

echo "${VAR1}"
echo "${VAR2}"

দুর্ভাগ্যক্রমে, "রাফেলস" -তে অ্যাডাস্ট্রোফ প্রথমটিকে কাজ করে না।
ডেনিস উইলিয়ামসন

উভয় কাজই শেষ পর্যন্ত আমার জন্য কাজ করে। ভিএআর 1 এর একক উদ্ধৃতিতে কোনও সমস্যা হওয়া উচিত নয় (কমপক্ষে ব্যাশের জন্য নয়)। সম্ভবত আপনি সিনট্যাক্স হাইলাইটিং দ্বারা বিভ্রান্ত হয়েছে?
joschi

1
এটি কোনও স্ক্রিপ্টে কাজ করে তবে বাশ প্রম্পটে নয়। পরিষ্কার না হওয়ার জন্য দুঃখিত।
ডেনিস উইলিয়ামসন

1
ইওএফ হিসাবে 'EOF'বা হিসাবে উদ্ধৃত করা ভাল "EOF", অন্যথায় শেল ভেরিয়েবলগুলি পার্স করা হবে।
স্ট্যানিস্লাভ জার্মানি-ইভতুশেনকো

13
#!/bin/sh

VAR1=`cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
  <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's "Foligno" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
`
echo "VAR1: ${VAR1}"

বোর্ন শেল পরিবেশের মধ্যে এটি সূক্ষ্মভাবে কাজ করা উচিত


1
এই সমাধানটি +1 করুন
able

উল্টো দিকে: sh- সামঞ্জস্যপূর্ণ। ডাউনসাইড: ব্যাকটিকগুলি ব্যাশে অবচিত / নিরুৎসাহিত করা হয়েছে। এখন যদি আমি sh এবং bash এর মধ্যে বেছে নিতে পারি ...
Zenexer

2
ব্যাকটিক্স কখন থেকে অবহেলা / নিরুৎসাহিত হয়? শুধু কৌতূহলী
আলেকজান্ডার মিলস

6

একই কাজ করার আরেকটি উপায় ...

আমি ভেরিয়েবল এবং বিশেষ <<-যারা স্ক্রিপ্ট ইনডেন্টেশন অনুমোদনের জন্য প্রতিটি লাইনের শুরুতে ট্যাবুলেশন ড্রপ ব্যবহার করতে চাই :

#!/bin/bash

mapfile Pattern <<-eof
        <?xml version="1.0" encoding='UTF-8'?>
        <painting>
          <img src="%s" alt='%s'/>
          <caption>%s, painted in
          <date>%s</date>-<date>%s</date>.</caption>
        </painting>
        eof

while IFS=";" read file alt caption start end ;do
    printf "${Pattern[*]}" "$file" "$alt" "$caption" "$start" "$end"
  done <<-eof
        madonna.jpg;Foligno Madonna, by Raphael;This is Raphael's "Foligno" Madonna;1511;1512
        eof

সতর্কতা : এর আগে কোনও ফাঁকা জায়গা নেই eofতবে কেবল সারণী

<?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
কিছু ব্যাখ্যা:
  • অ্যারেতে ম্যাপফাইলে পুরো এখানে ডকুমেন্ট পড়ে ।
  • সিনট্যাক্স "${Pattern[*]}"এই অ্যারেটিকে একটি স্ট্রিংয়ে ফেলে দেয়।
  • প্রয়োজনীয় স্ট্রিংগুলির IFS=";"কোনও নেই বলেই আমি ব্যবহার করি;
  • বাক্যলিপিটি স্ক্রিপ্টের বাকী অংশে পরিবর্তিত হওয়া while IFS=";" read file ...রোধ IFSকরে। এটিতে কেবল readপরিবর্তিত ব্যবহার করুন IFS
  • কাঁটাচামচ নেই

নোটের mapfileজন্য বাশ 4 বা তার বেশি প্রয়োজন requires ও সিনট্যাক্স "${Pattern[*]}"একটি স্ট্রিং মধ্যে অ্যারে কাস্ট যখন উদ্ধৃতির মধ্যে (যেমন উদাহরণ কোডে দেখানো হয়েছে)।
ডেনিস উইলিয়ামসন

হ্যাঁ, প্রশ্নটি যখন জিজ্ঞাসা করা হয়েছিল তখন বাশ 4 খুব নতুন ছিল।
এফ। হাউরি

2

অন্যান্য উত্তরগুলির মধ্যে অনেকগুলি কোণার মামলা রয়েছে।

স্পেস, ট্যাব, আইএফএস ইত্যাদির কোনও সমস্যা নেই তা পুরোপুরি নিশ্চিত করার জন্য, "হেরেডোক" কনস্ট্রাক্ট ব্যবহার করা ভাল, তবে uuencodeএখানে বর্ণিত হিসাবে হেরডোকের বিষয়বস্তুগুলি এনকোড করা :

https://stackoverflow.com/questions/6896025/#11379627

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.