সেডে পরিবেশগত পরিবর্তনশীল প্রতিস্থাপন


202

আমি যদি কোনও স্ক্রিপ্ট থেকে এই আদেশগুলি চালিত করি:

#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla

এটা উত্তম.

তবে, আমি যদি চালাই:

#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s' 

আমি টিউটোরিয়ালে পড়েছি যে শেল থেকে পরিবেশের ভেরিয়েবলগুলি প্রতিস্থাপন করতে আপনাকে থামাতে হবে, এবং $varnameঅংশটি 'আউট কোট' করতে হবে যাতে এটি সরাসরি প্রতিস্থাপন করা হয় না, যা আমি করেছি এবং যা কেবলমাত্র ভেরিয়েবলটি সংজ্ঞায়িত করার আগেই কাজ করে।

$varশেলটিতে সংজ্ঞায়িত হওয়ার সাথে সাথে পরিবেশের পরিবর্তনশীল হিসাবে আমি কীভাবে চিনতে পারি?


4
W পিডাব্লুডিতে একটি / থাকে যা বিকল্প কমান্ড শেষ করে।
ডারোবার্ট

@ডারবার্ট: টিএনএক্স। এর সমাধানগুলির মধ্যে একটি এটি সম্বোধন করে ...
রোমানম

4
set -xপ্রতিটি কমান্ড কার্যকর হওয়ার আগে শেলটি প্রতিধ্বনিত করতে শেলটি ব্যবহার করুন। এটি অনেকগুলি বিভ্রান্তি দূর করতে পারে। (এছাড়াও, আমি প্রায়ই ব্যবহার set -uডি উল্লেখ সেট না ভেরিয়েবল একটি হার্ড ভুল করার জন্য (দেখুন। set -eখুব)।)
bobbogo

আমি প্রক্রিয়া টেবিলের মধ্যে মানগুলি ফাঁস না করার জন্য পরিবেশের পরিবর্তনশীলগুলি পরিচালনা করার জন্য সেডের জন্য একটি উপায় খুঁজে প্রত্যাশা করছিলাম, মনে হচ্ছে
সেড

উত্তর:


302

আপনার দুটি উদাহরণ অভিন্ন দেখায়, যা নির্ণয় করতে সমস্যা করে। সম্ভাব্য সমস্যার:

  1. আপনার যেমন ডাবল উদ্ধৃতি প্রয়োজন হতে পারে sed 's/xxx/'"$PWD"'/'

  2. $PWDস্ল্যাশ, যে ক্ষেত্রে আপনি একটি চরিত্র বের করতে হবে থাকতে পারে না অন্তর্ভুক্ত $PWDএকটি বিভেদক হিসাবে ব্যবহার করার জন্য।

উভয় ইস্যু একসাথে পেরেক করা, সম্ভবত

sed 's@xxx@'"$PWD"'@'

তবে, তবে আমি কী চরিত্রটি ব্যবহার করতে পারি তা আমি নিশ্চিতভাবে জানি যে কোনও নামের নামে উপস্থিত হবে না?
রোমানম

5
আপনার কাছে @ #% এর মতো বেশ কয়েকটি প্রার্থী থাকতে পারে! এবং কেস এক্সপ্রেশন দিয়ে পরীক্ষা করে দেখুন $ পিডাব্লুডিতে সেগুলি রয়েছে কিনা। উদাহরণস্বরূপ, কেস "$ পিডাব্লুডি" এর @ ) ;; *) ডিলিম = "@" ;; esac; $ ডিলিম খালি না হওয়া পর্যন্ত পুনরাবৃত্তি করুন।
নরম্যান রামসে

ডাবল উদ্ধৃতি ব্যবহারের পরিবর্তে আরও একটি বিকল্প রয়েছে। আমার উত্তর নীচে দেখুন।
থ্যালস সিওলিন 13

আপনি শেডের জন্য অন্য একটি ডিলিমিটার ব্যবহার করতে পারেন। আপনার ব্যবহারের প্রয়োজন নেই / আপনি ব্যবহার করতে পারবেন, পাশাপাশি যদি আপনার পরিবেশের পরিবর্তনশীল একটি url হয়।
গুচেলকাবেন

123

নরম্যান রামসির উত্তর ছাড়াও, আমি যুক্ত করতে চাই আপনি পুরো স্ট্রিংকে ডাবল-কোট করতে পারেন (যা বিবৃতিটি আরও পঠনযোগ্য এবং কম ত্রুটির প্রবণ হতে পারে)।

সুতরাং আপনি যদি 'foo' অনুসন্ধান করতে চান এবং এটি $ BAR এর বিষয়বস্তু দিয়ে প্রতিস্থাপন করতে চান, আপনি ডাবল-উদ্ধৃতিতে সেড কমান্ডটি আবদ্ধ করতে পারেন।

sed 's/foo/$BAR/g'
sed "s/foo/$BAR/g"

প্রথমদিকে, $ BAR সঠিকভাবে প্রসারিত হবে না যখন দ্বিতীয় $ BAR সঠিকভাবে প্রসারিত হবে।


4
এটি ডাবল কোট, একক উদ্ধৃতি ইত্যাদির সাথে
জগাখিচির

এই কমান্ডটিতে পরিবেশের পরিবর্তনশীলটি সঠিকভাবে প্রসারিত করার জন্য আমার এই
জিনিসটি

2
এই ঝরঝরে কিন্তু এটা কাজ করছে না যখন আপনি আরো কিছু জটিল বদল যেমন কাজ করতে চান "2,$s/^/$foo/"যেমন $sএকটি পরিবর্তনশীল হিসাবে খুব ব্যাখ্যা পরার এবং এটি না করা উচিত।
এমজেপি

59

আপনি প্রতিস্থাপনে "/" ছাড়াও অন্যান্য অক্ষর ব্যবহার করতে পারেন:

sed "s#$1#$2#g" -i FILE

আমার নির্দিষ্ট ক্ষেত্রে, $ 2 একটি ফাইল পাথ sedছিল , সুতরাং /$ 2 এর সামগ্রীগুলিতে ব্যাখ্যার কারণে বারফিং ছিল । এটি পাস করার জন্য আমার ঠিক এটির দরকার ছিল। ধন্যবাদ ফোরা দুর্দান্ত টিপ!
বয়ড হেমফিল

54

আর একটি সহজ বিকল্প:

যেহেতু $PWDসাধারণত একটি স্ল্যাশ থাকবে /, সেড স্টেটমেন্টের |পরিবর্তে ব্যবহার করুন /:

sed -e "s|xxx|$PWD|"

4
আপনি "ডাবল উদ্ধৃতি ব্যবহারের বিকল্প" বলেছিলেন এবং এখনও আপনার উদাহরণটি ডাবল উক্তি ব্যবহার করে?
পৌঁছান

আমার ধারণাটি হ'ল এটি কি সরাসরি চারপাশে ডাবল-কোট ব্যবহার করে না $PWD...?
খ্রিস্টান

14

আপনার প্রশ্ন সম্পাদনা, আমি আপনার সমস্যা দেখতে। আসুন এখনকার ডিরেক্টরিটি হ'ল /home/yourname ... এই ক্ষেত্রে, আপনার নীচের আদেশটি:

sed 's/xxx/'$PWD'/'

প্রসারিত হবে

sed `s/xxx//home/yourname//

যা বৈধ নয়। আপনি যদি এটি করতে চান তবে আপনাকে নিজের $ পিডাব্লুডির \প্রত্যেকটির সামনে একটি চরিত্র /রাখতে হবে।


তবে পিডব্লিউডি শেল দ্বারা সংজ্ঞায়িত করা হয় ... আমি যদি প্রতিধ্বনি go পিডাব্লুডিতে যাই তবে আমি পিডব্লুডি
পাই

1
সুতরাং, আপনি পরিবেশের পরিবর্তনশীলগুলি কীভাবে এড়াতে পারবেন?
einpoklum

1
নির্বাচিত উত্তরটি একটি কার্যবিবরণী বর্ণনা করে ... ডিলিমিটারের জন্য স্ল্যাশ ব্যবহার করবেন না
এডি

আপনার বর্তমান ওয়ার্কিং ডিরেক্টরিতে অন্য চরিত্রটি অন্তর্ভুক্ত হওয়ার সাথে সাথে এটি কোনও সমস্যা হয়ে উঠবে।
blubberdiblub

6

খারাপ উপায়: পরিবর্তনসীমা পরিবর্তন করুন

sed 's/xxx/'"$PWD"'/'
sed 's:xxx:'"$PWD"':'
sed 's@xxx@'"$PWD"'@'

সম্ভবত যারা চূড়ান্ত উত্তর না,

কোন অক্ষরটি ঘটবে তা আপনি জানতে পারবেন না $PWD, / :বা @

ভাল উপায় বিশেষ চরিত্রটি প্রতিস্থাপন করা হয় $PWD

ভাল উপায়: পালক সীমানা

উদাহরণস্বরূপ: URL$ url হিসাবে প্রতিস্থাপন করার চেষ্টা করুন ( : /সামগ্রীতে রয়েছে)

x.com:80/aa/bb/aa.js

স্ট্রিং $ tmp এ

<a href="URL">URL</a>

ক। /সীমানা হিসাবে ব্যবহার

echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js

echo ${url//\//\/}
x.com:80/aa/bb/aa.js

echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js

echo $tmp | sed "s/URL/${url//\//\\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

echo $tmp | sed "s/URL/${url//\//\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

অথবা

খ। :ডিলিমিটার হিসাবে ব্যবহার করুন (এর চেয়ে বেশি পাঠযোগ্য /)

echo ${url//:/\:}
x.com:80/aa/bb/aa.js

echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js

echo $tmp | sed "s:URL:${url//:/\:}:g"
<a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>

3

আসলে, সবচেয়ে সহজ জিনিসটি (কমপক্ষে gnu সেডে) সেড সাবস্টিটিউশন (গুলি) কমান্ডের জন্য একটি পৃথক বিভাজক ব্যবহার করা। সুতরাং s / প্যাটার্ন / '$ মাইপাথ' / এর পরিবর্তে এস / প্যাটার্নে প্রসারিত করা হবে // আমার / পথ / যা অবশ্যই s কমান্ডকে বিভ্রান্ত করবে, s! প্যাটার্নটি ব্যবহার করুন! '$ মাইপথ'! যা প্রসারিত হবে! প্যাটার্ন! / আমার / পাথ! আমি ব্যাং (!) চরিত্রটি ব্যবহার করেছি (বা আপনার পছন্দ মতো কিছু ব্যবহার করুন) যা স্বাভাবিকটি এড়িয়ে যায়, তবে কোনও-কোনও-নয়-আপনার একমাত্র-পছন্দ-পূর্ববর্তী স্ল্যাশকে বিভাজক হিসাবে।


3
VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1' 

যেখানে ভিএআর-তে আপনি যা ক্ষেত্রটি প্রতিস্থাপন করতে চান তা ধারণ করে


3

সেডের মধ্যে পৃথকগুলি নিয়ে কাজ করা

[root@gislab00207 ldom]# echo domainname: None > /tmp/1.txt

[root@gislab00207 ldom]# cat /tmp/1.txt

domainname: None

[root@gislab00207 ldom]# echo ${DOMAIN_NAME}

dcsw-79-98vm.us.oracle.com

[root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g'

 --- Below is the result -- very funny.

domainname: ${DOMAIN_NAME}

 --- You need to single quote your variable like this ... 

[root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g'


--- The right result is below 

domainname: dcsw-79-98vm.us.oracle.com

আমি আজুর ডিভোপস ওয়াইএএমএল পাইপলাইনগুলিতে এটি কাজ করার জন্য সংগ্রাম করছি। এই মন্তব্যটি আমাকে কিছু কৌশলগত ফাইল টোকানাইজ করতে সফলভাবে এই কৌশলটি ব্যবহার করতে সহায়তা করেছে।
andov

1

আমার একই সমস্যা ছিল, আমার একটি তালিকা ছিল এবং আমাকে টেমপ্লেটের উপর ভিত্তি করে একটি এসকিউএল স্ক্রিপ্ট তৈরি করতে হবে (এতে @INPUT@প্রতিস্থাপনের জন্য উপাদান হিসাবে রয়েছে ):

for i in LIST 
do
    awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.