অতিরিক্ত স্থান সহ একাধিক-লাইনের স্ট্রিং (সংরক্ষণিত ইনডেন্টেশন)


409

নিম্নলিখিত ফাইলগুলির সাথে আমি কয়েকটি প্রাক-সংজ্ঞায়িত পাঠ্য লিখতে চাই:

text="this is line one\n
this is line two\n
this is line three"

echo -e $text > filename

আমি এরকম কিছু প্রত্যাশা করছি:

this is line one
this is line two
this is line three

তবে এটি পেয়েছি:

this is line one
 this is line two
 this is line three

আমি ইতিবাচক যে প্রত্যেকের পরে কোনও স্থান নেই \n, তবে কীভাবে অতিরিক্ত স্থান বের হয়?


2
আমি নিশ্চিত নই .. তবে আপনি যদি কেবল text="this is line one\nthis is line two\nthis is line three"একই লাইনে টাইপ করেন ..? (কোনও প্রবেশ ছাড়াই)
যোহানেস খোসিয়াওয়ান 许先汉

4
\nপ্রতিটি লাইনের
অনটি

আপনি ইতিমধ্যে দিয়েছেন। সুতরাং আপনি \nকেন নতুন লাইনে পরের লাইনটি রেখেছেন? সহজভাবেtext="this is line one\nthis is line two\nthis is line three"
জয়েশ ভোই

1
\nপ্রতিটি লাইনের শেষে অপসারণের ফলে আউটপুট একসাথে একক লাইনে চলে যায়।
জোনাথন হার্টলি

18
আহা: "$text"প্রতিধ্বনি রেখার চারপাশে ডাবল কোট লাগানো অত্যন্ত গুরুত্বপূর্ণ। এগুলি ব্যতীত নতুন লাইনের কোনওটিই (আক্ষরিক এবং '\ n') কাজ করে না। তাদের সাথে, তারা সবাই করে।
জোনাথন হার্টলি 18 ই

উত্তর:


662

এই উদ্দেশ্যে হেরাদোক আরও সুবিধাজনক বলে মনে হচ্ছে। এটি প্রাক্তন বা বিড়ালের মতো কমান্ড ইন্টারপ্রেটার প্রোগ্রামে একাধিক কমান্ড প্রেরণে ব্যবহৃত হয়

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

স্ট্রিংয়ের পরে <<কোথায় থামতে হবে তা নির্দেশ করে।

এই লাইনে কোনও ফাইলে প্রেরণ করতে, ব্যবহার করুন:

cat > $FILE <<- EOM
Line 1.
Line 2.
EOM

আপনি এই লাইনগুলি একটি ভেরিয়েবলের মধ্যেও সংরক্ষণ করতে পারেন:

read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM

এটি ভেরিয়েবল নামের রেখাগুলি সংরক্ষণ করে VAR

মুদ্রণের সময়, ভেরিয়েবলের চারপাশে উদ্ধৃতিগুলি মনে রাখবেন অন্যথায় আপনি নতুন লাইন অক্ষর দেখতে পাবেন না।

echo "$VAR"

আরও ভাল, আপনি আপনার কোডটিতে আরও স্ট্যান্ড করে তুলতে আপনি ইন্ডেন্টেশন ব্যবহার করতে পারেন। এই বারে ট্যাবগুলি প্রদর্শিত হওয়া বন্ধ করতে কেবল একটি -পরে যুক্ত করুন <<

read -r -d '' VAR <<- EOM
    This is line 1.
    This is line 2.
    Line 3.
EOM

তবে তারপরে আপনার কোডে ইনডেন্টেশন করার জন্য আপনাকে অবশ্যই ফাঁকা স্থানগুলি নয়, ট্যাব ব্যবহার করতে হবে।


38
২ য় এবং ৫ ম কোড ব্লকের প্রথম লাইনে আপনার << - এর পরিবর্তে <<? কি - বিশেষ কিছু না?
লোহফু

35
@ sup3rman '-' শীর্ষস্থানীয় ট্যাবগুলিকে উপেক্ষা করে। দেখুন stackoverflow.com/questions/2500436/...
kervin

7
আমি কীভাবে স্ট্যাটাস 0 দিয়ে পঠন প্রস্থান করতে পারি? দেখে মনে হচ্ছে এটি লাইনের শেষটি খুঁজে পাচ্ছে না (যেহেতু এটি '-d' ') এবং এটি 1 দিয়ে প্রস্থান করে যা আপনি স্ক্রিপ্টে থাকা অবস্থায় সহায়তা করে না।
মিশা স্লিউসারেভ

6
@ মিশা স্লিউসারেভ -d '\ 0' ব্যবহার করুন এবং আপনার শেষ লাইনের শেষে একটি \ 0 যুক্ত করুন
লার্স স্নাইডার

11
ব্যবহার -dবিকল্পটি read -r -d '' VARIABLE <<- EOMআমার জন্য কাজ করে নি।
dron22

186

আপনি যদি স্ট্রিংটিকে একটি ভেরিয়েবলে আনার চেষ্টা করছেন তবে অন্য একটি সহজ উপায় হ'ল:

USAGE=$(cat <<-END
    This is line one.
    This is line two.
    This is line three.
END
)

আপনি যদি আপনার স্ট্রিংটিকে ট্যাবগুলি (যেমন, '\ t') দিয়ে ইনডেন্ট করেন তবে ইনডেন্টেশনটি কেটে ফেলা হবে। যদি আপনি স্পেস দিয়ে ইন্ডেন্ট করেন তবে ইনডেন্টেশনটি বাকি থাকবে।

দ্রষ্টব্য: এটি হল যে গত সমাপনী প্রথম বন্ধনী অন্য লাইন হয় উল্লেখযোগ্য। ENDটেক্সট নিজে একটি লাইন প্রদর্শিত উচিত নয়।


1
তা কি তাৎপর্যপূর্ণ? )একই লাইনে আমার ম্যাকের সাথে কাজ করে । আমি মনে করি এটি এর কারণ যা তার মধ্যে রয়েছে $(এবং )তার নিজস্ব মহাবিশ্বের মধ্যে এটি কার্যকর হবে এবং প্রকৃত আদেশটি ')' কোনওভাবেই দেখতে পাবে না। আমি ভাবছি যদি এটি অন্যদের জন্যও কাজ করে।
দেজ

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

মজার বিষয় হ'ল, ইউএসএজি ভেরিয়েবলের জন্যও মান নির্ধারণ করার সময় আমি উত্তর পেয়েছি। সুতরাং আপনার উত্তর ঠিক মেলে। :)
বুনিক

1
থেকে @deej POSIX বৈশিষ্ট : এখানে নথি ... চলতে থাকে যতক্ষণ সেখানে মাত্র বিভেদক এবং একটি <সম্পর্কে newline> ধারণকারী একটি লাইন
Fornost

1
@ ফার্নোস্ট এটি আমি যা বলেছি তার সাথে বিরোধিতা করে না
দিজেজ

84

echoএটিতে দেওয়া আর্গুমেন্টগুলির মধ্যে ফাঁকা স্থান যুক্ত করে। $textপরিবর্তনশীল সম্প্রসারণ এবং শব্দ বিভাজনের সাপেক্ষে আপনার echoআদেশটি সমান:

echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n"  ...

আপনি দেখতে পাচ্ছেন যে "এটি" এর আগে একটি স্থান যুক্ত করা হবে। আপনি হয় নিউলাইন অক্ষরগুলি মুছে ফেলতে পারেন, এবং $textনিউলাইনগুলি সংরক্ষণের জন্য উদ্ধৃতি দিতে পারেন:

text="this is line one
this is line two
this is line three"

echo "$text" > filename

বা আপনি ব্যবহার করতে পারেন printf, যা এর চেয়ে মজবুত এবং বহনযোগ্য echo:

printf "%s\n" "this is line one" "this is line two" "this is line three" > filename

ইন bash, যা ব্রেস প্রসারকে সমর্থন করে, আপনি এমনকি করতে পারেন:

printf "%s\n" "this is line "{one,two,three} > filename

1
"ইকো" কমান্ডটি ব্যবহার করার সময় মোড কেন অতিরিক্ত স্থান দেখেন তা বোঝানোর জন্য ধন্যবাদ Thanks এই উত্তরটিও ব্যাশ স্ক্রিপ্টে ব্যবহার করার সময় (ইন্টারেক্টিভ শেল সেশনের বিরোধিতা হিসাবে) ভাল কাজ করছে। এটিকে আসল উত্তর বলে মনে হয় এবং এটি একটি স্বীকৃত উত্তর হওয়া উচিত।
একলভিউ

1
এটি উত্তর গ্রহণ করা উচিত। অন্যান্য সমস্ত উত্তর ওপির ব্যথার সমাধানের জন্য আরও অনেক আকর্ষণীয় অন্যান্য উপায় সরবরাহ করেছিল, তবে প্রযুক্তিগতভাবে প্রশ্নটি ছিল "অতিরিক্ত স্থান কীভাবে বেরিয়ে আসে" এবং এটিকে কেউ সম্বোধন করেনি :-) !!! ধন্যবাদ, -১ রহস্য তৈরির জন্য জোশ!
দিমিত্রি শেভকপলিয়াস

45

একটি বাশ স্ক্রিপ্টে নিম্নলিখিত কাজ করে:

#!/bin/sh

text="this is line one\nthis is line two\nthis is line three"
echo -e $text > filename

অন্যথায়:

text="this is line one
this is line two
this is line three"
echo "$text" > filename

বিড়াল ফাইলের নাম দেয়:

this is line one
this is line two
this is line three

মনে হচ্ছে বিকল্প কৌশলটি শেল স্ক্রিপ্টস চলাকালীন কাজ করে তবে এটি ব্যাশের জন্য কাজ করে বলে মনে হয় না।
ম্যাকিন্ডো

3
@Macindows আমি ভুলে গেছি বলে মনে হচ্ছে -eজন্য বিকল্প echo। আবার চেষ্টা করুন.
ক্রিস মায়েস

41

যেহেতু আমি প্রতিটি লাইনে সঠিকভাবে ইন্টেন্ট করাতে চেয়েছিলাম আমি আরও সমাধান পেয়েছি:

  1. আপনি ব্যবহার করতে পারেন echo:

    echo    "this is line one"   \
        "\n""this is line two"   \
        "\n""this is line three" \
        > filename

    আপনি যদি কোনও লাইনের শেষে "\n"আগে \রাখেন তবে এটি কাজ করে না ।

  2. বিকল্পভাবে, আপনি printfআরও ভাল বহনযোগ্যতার জন্য ব্যবহার করতে পারেন (এতে আমার অনেক সমস্যা হয়েছে echo):

    printf '%s\n' \
        "this is line one"   \
        "this is line two"   \
        "this is line three" \
        > filename
  3. তবুও অন্য সমাধান হতে পারে:

    text=''
    text="${text}this is line one\n"
    text="${text}this is line two\n"
    text="${text}this is line three\n"
    printf "%b" "$text" > filename

    অথবা

    text=''
    text+="this is line one\n"
    text+="this is line two\n"
    text+="this is line three\n"
    printf "%b" "$text" > filename
  4. আর একটি সমাধান মেশানো দ্বারা অর্জন করা হয় printfএবং sed

    if something
    then
        printf '%s' '
        this is line one
        this is line two
        this is line three
        ' | sed '1d;$d;s/^    //g'
    fi

    আপনি কোডটিতে ইনডেন্টেশন স্তরটিকে হার্ডকোড করায় রিফ্যাক্টর কোডটি এভাবে ফর্ম্যাট করা সহজ নয়।

  5. কোনও সহায়ক ফাংশন এবং কিছু পরিবর্তনশীল প্রতিস্থাপন কৌশল ব্যবহার করা সম্ভব:

    unset text
    _() { text="${text}${text+
    }${*}"; }
    # That's an empty line which demonstrates the reasoning behind 
    # the usage of "+" instead of ":+" in the variable substitution 
    # above.
    _ ""
    _ "this is line one"
    _ "this is line two"
    _ "this is line three"
    unset -f _
    printf '%s' "$text"

স্বতন্ত্রভাবে কোড ইনডেন্টেশন এবং স্ট্রিং ইন্ডেন্টেশন সংরক্ষণ করতে চাইলে 3 বি আমার পছন্দের সমাধান হ'ল কমপক্ষে যখন আমি ভেরিয়েবল অ্যাসাইনমেন্টে 2 ব্যবহার করতে পারি না এবং 3 এ এর ​​চেয়ে বেশি পঠনযোগ্য। আমি যখন খেয়াল রাখিনা আমি উদ্ধৃত স্ট্রিংটি বেশ কয়েকটি লাইনের ওপরে রাখি।
পিসিস

খুব সুন্দর উত্তর বিশেষত 3 বি
সুমিত ত্রিহান 10'19

"আপনি কোনও লাইনের শেষে" before n "এর আগে put n রেখে দিলে এটি কাজ করে না" " প্রতিধ্বনি ব্যবহার করার সময় একটি দুর্দান্ত টিপ is
নোয়াম মানস

6

একটি ভেরিয়েবলের জন্য মাল্টি-লাইন স্ট্রিং নির্ধারণ করার জন্য নীচে আমার পছন্দের উপায়টি (আমি মনে করি এটি দেখতে সুন্দর দেখাচ্ছে)।

read -r -d '' my_variable << \
_______________________________________________________________________________

String1
String2
String3
...
StringN
_______________________________________________________________________________

উভয় ক্ষেত্রে আন্ডারস্কোরগুলির সংখ্যা একই (এখানে 80)।


0

এটি একটি সহজ এক-লাইন সংমিশ্রণের উল্লেখ করার জন্য এটি কখনও কখনও দরকারী হতে পারে।

# for bash

v=" guga "$'\n'"   puga "

# Just for an example.
v2="bar "$'\n'"   foo "$'\n'"$v"

# Let's simplify the previous version of $v2.
n=$'\n'
v3="bar ${n}   foo ${n}$v"

echo "$v3" 

আপনি এই জাতীয় কিছু পাবেন

বার 
   foo বিন্যাস 
 guga 
   বোতাম 

সমস্ত নেতৃস্থানীয় এবং শেষ হওয়া শ্বেত স্থান সঠিকভাবে সংরক্ষণ করা হবে

echo "$v3" > filename

0

এটি করার অনেকগুলি উপায় রয়েছে। আমার জন্য, মধ্যে ইন্ডেন্টযুক্ত স্ট্রিং বংশীধ্বনিতুল্য sed চমত্কারভাবে কাজ করে।

printf_strip_indent() {
   printf "%s" "$1" | sed "s/^\s*//g" 
}

printf_strip_indent "this is line one
this is line two
this is line three" > "file.txt"

এই উত্তরটি মাতেউজ পিয়োত্রস্কির উত্তরের ভিত্তিতে ছিল তবে কিছুটা পরিশ্রুত হয়েছে।


-1

আপনি এটি নীচের মত রাখলে এটি কাজ করবে:

AA='first line
\nsecond line 
\nthird line'
echo $AA
output:
first line
second line
third line
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.