বাশ: একটি ভেরিয়েবলের প্রথম লাইনটি নির্ধারণ করা ign


11

আমার একটি মাল্টলাইন ভেরিয়েবল রয়েছে এবং আমি কেবল সেই ভেরিয়েবলের প্রথম লাইনটি চাই। নিম্নলিখিত লিপিটি সমস্যাটি দেখায়:

#!/bin/bash

STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"

echo "  Take the first line and send to standard output:"
echo ${STRINGTEST%%$'\n'*}
#   Output is as follows:
# Onlygetthefirstline

echo "  Set the value of the variable to the first line of the variable:"
STRINGTEST=${STRINGTEST%%$'\n'*}

echo "  Send the modified variable to standard output:"
echo $STRINGTEST
#   Output is as follows:
# Onlygetthefirstline butnotthesecond orthethird

প্রশ্ন: কমান্ডের ${STRINGTEST%%$'\n'*}পরে echoস্থাপনের পরে প্রথম লাইনটি কেন ফিরে আসে , তবে কার্যনির্বাহের পরে স্থাপনের পরে স্থানগুলি দিয়ে নতুন লাইনগুলি প্রতিস্থাপন করে?


1
এটি পুনরুত্পাদন করতে পারবেন না। এটি প্রত্যাশা মতো আমার জন্য কাজ করে।
পেক

1
2.05b, 3.1, 3.2, 4.0, 4.1, 4.2, 4.3 এর যে কোনও একটির সাথে পুনরুত্পাদন করা যাবে না। $'...'ব্যাশ এর পরিবর্তে সমর্থন করে না এমন শেল দিয়ে চালানোর চেষ্টা করার মতো ব্যবহারকারীর ত্রুটির মতো মনে হচ্ছে ।
স্টাফেন চেজেলাস 22'15

উত্তর:


8

আপনি যা করতে চান সেটি সংরক্ষণ করার জন্য অন্য কোনও উপায় থাকতে পারে তবে এটি কাজ করে

#!/bin/bash

STRINGTEST="
Onlygetthefirstline
butnotthesecond
orthethird
"

STRINGTEST=(${STRINGTEST[@]})
echo "${STRINGTEST[0]}"

এটি ধরে রেখেছে যে রেখাগুলিতে $STRINGTESTফাঁকা বা ওয়াইল্ডকার্ড নেই। এছাড়াও নোট করুন যে খালি লাইনগুলি (সেই পরিবর্তনকের প্রথম লাইনে যেমন) উপেক্ষা করা হবে।
স্টাফেন চ্যাজেলাস

3
এছাড়াও মনে রাখবেন যে ব্যবহারটি STRINGTEST=(${STRINGTEST[@]})সামান্য অর্থবোধ করে এবং এর আগে STRINGTEST=($STRINGTEST)যেহেতু STRINGTESTআগে স্কেলার ( অ্যারে নয় ) ভেরিয়েবল হিসাবে সংজ্ঞায়িত হয়েছিল তার সমতুল্য ।
স্টাফেন চেজেলাস

10

সবচেয়ে দক্ষ না হতে পারে তবে একটি লাইনার ...

firstLine=`echo "${multiLineVariable}" | head -1`

2
আমি এটি স্পষ্টতা এবং সংকোচনের জন্য পছন্দ করি।
পিটার - মনিকা পুনরায়

এই firstLine=`echo "${test_var}" | sed -n 1pযদি আপনি যদি এর পরিবর্তে sed ব্যবহার করার জন্য একটি কারণ আছে কাজ (যেমন, তার মানে আপনি একযোগে লাইন প্রতিস্থাপনের সম্পাদন করতে পারবেন: echo "${test_var}" | sed -nE '1 s/# *(.*)/\1/p'
robenkleene

7

এই কোডটি আমার পক্ষে 2.05b এবং 4.3 এর মধ্যে চেষ্টা করা সমস্ত বাশ এর সংস্করণ নিয়ে কাজ করে। সম্ভবত আপনি সেই স্ক্রিপ্টটি কোনও আলাদা শেল দিয়ে চালানোর চেষ্টা করেছেন $'...'যা উদ্ধৃতি রূপকে সমর্থন করে না ।

যে $'...'বাক্য গঠন মান নয় shসিনট্যাক্স (এখনও) এবং শুধুমাত্র (2015-05-22 এবং আমি যতদূর জানি হিসাবে) সমর্থিত দ্বারা ksh93(যেখানে এটি সম্ভূত), zsh, bash, সাম্প্রতিক সংস্করণ mkshএবং shFreeBSD 'র অথবা সাম্প্রতিক সংস্করণ

আমার বাজি হবে আপনার সাথে স্ক্রিপ্ট চালানোর চেষ্টা করে shপরিবর্তে bashএবং আপনার shসংস্করণের উপর ভিত্তি করে তৈরি ash, pdksh, yashবা ksh88এটি এখনো সমর্থন করি না।

আপনি যদি সেই কোডটি পসিক্স ২০০৮ সামঞ্জস্যপূর্ণ করতে চান তবে আপনার এটি লিখতে হবে:

STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"

NL='
'
STRINGTEST=${STRINGTEST%%"$NL"*}
printf '%s\n' "$STRINGTEST"

তারপরে, আপনি এটির মতো কোনও পসিক্স কমপ্লায়েন্ট শেল bashবা আপনার মতো কোনও পাতলা / দ্রুতগতির দ্বারা ব্যাখ্যা করতে পারেন sh

(এবং মনে রাখবেন যে তালিকার প্রেক্ষাপটে বিন্যস্ত একটি পরিবর্তনীয় রেখে যাওয়ার বোর্নের মতো শেলগুলির খুব বিশেষ অর্থ রয়েছে)।


বা এটি ব্যাশের পুরানো সংস্করণ হতে পারে। আমি 2.03 এর সাথে আচরণটি পুনরুত্পাদন করতে পারি।
গিলস

@ গিলস, সর্বশেষ সমর্থিত ওএস যা বাশ -০.০৩ অন্তর্ভুক্ত করেছিল (১ years বছর আগে প্রকাশিত হয়েছিল) সম্ভবত সোলারিস ৮ ছিল যা OL বছর আগে ইওএল গিয়েছিল। এই অনুমানটি বেশ অসম্ভব বলে মনে হচ্ছে।
স্টাফেন চেজেলাস

1

এটি আমার পক্ষে কাজ করে:

STRINGTEST="Some Text 1
Some Text 2
Some Text 3"

readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"

এবং এটি ফাঁকা লাইনের জন্যও কাজ করে:

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"

readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"

যদি কেউ প্রক্রিয়া প্রতিস্থাপন বন্ধ করতে বিরক্ত করে তবে কেউ readএকবার সহজ ভেরিয়েবলের ( readarrayপ্লাস ইনডেক্সিংয়ের পরিবর্তে ) পরিবর্তিত হতে পারে ।
পিটার - মনিকা পুনরায়

0

অন্তর্নির্মিত readএবং এখানে-স্ট্রিং সহ বাশ :

#!/usr/bin/env bash

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"


IFS=$'\n' read -r STRINGTEST <<<"$STRINGTEST"

পসিক্স প্যারামিটার সম্প্রসারণ ব্যবহার:

#!/usr/bin/env sh

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"

# Disables globing
set -f

# Field separator is newline only
IFS="
"

# No quotes, split lines as arguments because of IFS
set -- $STRINGTEST

# First argument is first line
STRINGTEST="$1"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.