শেবাংয়ে `/ usr / bin / env sed -f use ব্যবহারের উপায়?


25

/usr/bin/env sed -fটার্মিনাল কাজ টাইপ ।

তবে যদি এটি শেবাং হিসাবে ব্যবহার করে,

#!/usr/bin/env sed -f 
s/a/b/

স্ক্রিপ্টটি কার্যকর করতে ব্যর্থ হবে:

/usr/bin/env: sed -f: No such file or directory

আমি এক ধরনের বিশ্বাস করি যে এটি -ফের সাথে সম্পর্কিত। তবে কীভাবে এর সমাধান করবেন?


উত্তর:


33

আপনি, বহনযোগ্যভাবে, একটি #!লাইনে একাধিক যুক্তি রাখতে পারবেন না । এর অর্থ কেবল একটি সম্পূর্ণ পথ এবং একটি তর্ক (যেমন #!/bin/sed -fবা #!/usr/bin/sed -f), বা #!/usr/bin/envদোভাষীটির পক্ষে কোনও যুক্তি।

পোর্টেবল স্ক্রিপ্ট পাওয়ার জন্য একটি কার্যপ্রণালী হ'ল #!/bin/shকমান্ড-লাইন আর্গুমেন্ট হিসাবে সেড স্ক্রিপ্টটি পাস করে একটি শেল র‌্যাপার ব্যবহার করা । নোট করুন যে এটি পসিক্স দ্বারা অনুমোদিত নয় (মাল্টি-নির্দেশনা স্ক্রিপ্টগুলি অবশ্যই -eবহনযোগ্যতার জন্য প্রতিটি নির্দেশের জন্য পৃথক যুক্তি দিয়ে লিখতে হবে ), তবে এটি অনেকগুলি বাস্তবায়নের সাথে কাজ করে works

#!/bin/sh
exec sed '
s/a/b/
' "$@"

দীর্ঘ স্ক্রিপ্টের জন্য, হেরডোক ব্যবহার করা আরও সুবিধাজনক হতে পারে। হেরডোকের একটি সুবিধা হ'ল আপনার যদি ভিতরে কোনও একক উক্তি উদ্ধৃত করার প্রয়োজন হয় না। একটি বড় ক্ষয়ক্ষতি হ'ল স্ক্রিপ্টটি দুটি স্ট্র্যান্ডিং পরিণতি সহ স্ট্যান্ডার্ড ইনপুট এনে দেওয়া হয়। এর -f /dev/stdinপরিবর্তে সেডের কিছু সংস্করণ প্রয়োজন -f -, যা বহনযোগ্যতার জন্য সমস্যা। সবচেয়ে খারাপ, স্ক্রিপ্টটি ফিল্টার হিসাবে কাজ করতে পারে না, কারণ স্ট্যান্ডার্ড ইনপুটটি স্ক্রিপ্ট এবং ডেটা হতে পারে না।

#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF

হেরডোকের ডাউনসাইডটি একটি দরকারী ব্যবহারের মাধ্যমে প্রতিকার করা যেতে পারে cat। যেহেতু এটি পুরো স্ক্রিপ্টটি আবার কমান্ড লাইনে ফেলেছে, এটি পসিক্স-কমপ্লায়েন্ট নয়, তবে বাস্তবে বহুলাংশে বহনযোগ্য।

#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF

আরেকটি কর্মসূচী হ'ল একটি স্ক্রিপ্ট লিখুন যা sh এবং সেড উভয় দিয়ে পার্স করা যায়। এটি বহনযোগ্য, যুক্তিসঙ্গত দক্ষ, কিছুটা কুৎসিত।

#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/

ব্যাখ্যা:

  • আন্ডার শ: একটি ফাংশন সংজ্ঞায়িত b; ফাংশনটি সিনট্যাকটিকভাবে সু-গঠনযুক্ত হওয়াতে বিষয়বস্তুগুলির ততক্ষণ গুরুত্বপূর্ণ নয় (বিশেষত, আপনার খালি ফাংশন থাকতে পারে না)। তারপরে যদি সত্য হয় (যেমন সর্বদা), sedস্ক্রিপ্টে চালিত করুন।
  • অধীন সেড: ()লেবেলে শাখা , তারপরে কিছু সুসংহত ইনপুট। তারপরে একটি iকমান্ড, যার কোনও প্রভাব নেই কারণ এটি সর্বদা এড়িয়ে যায়। পরিশেষে ()লেবেলটি স্ক্রিপ্টের দরকারী অংশ অনুসরণ করে।
  • GNU সেড, ব্যাসিবক্স এবং ওপেনবিএসডি এর অধীনে পরীক্ষিত। (আপনি জিএনইউ সেডে সহজ কিছু দিয়ে পালাতে পারেন, তবে ওপেনবিএসডি সেডটি যে অংশগুলি এড়িয়ে যায় সেগুলি সম্পর্কে মজাদার))

1
"বা #!/usr/bin/envএবং কোন তর্ক নেই।" খুব ভাল শব্দযুক্ত না। সম্ভবত "বা #!/usr/bin/env sedএবং সেড করার কোনও যুক্তি নেই।"
সিজেএম

"মাত্র কিছুটা কুৎসিত" এবং দ্বৈত ভাষার স্ক্রিপ্টের জন্য +1 :)
8:48

6

ওএসের উপর নির্ভর করে শেবাং (#!) এর বিভিন্ন বেমানান বাস্তবায়ন রয়েছে। কেউ একটি সম্পূর্ণ আর্গুমেন্ট তালিকা তৈরি করছে, কেউ কমান্ড পাথ সংরক্ষণ করছে এবং বাকী সমস্ত আর্গুমেন্টকে একক হিসাবে রাখে, কেউ কেউ সমস্ত যুক্তি উপেক্ষা করে কেবল কমান্ডের পথটি পাস করে এবং শেষ পর্যন্ত কেউ কেউ পুরো স্ট্রিংটিকে একক হিসাবে পাস করছে কমান্ড। আপনি উত্তরোত্তর ক্ষেত্রে মনে হয়।


2

এনভিভি "সেড-এফ" নামের একটি ফাইল সন্ধান করার চেষ্টা করছে। আপনি আপনার শেবাং লাইন হিসাবে "#! / Usr / bin / sed -f" চেষ্টা করতে পারেন


2

জিএনইউ কোর্টিলস ভি 8.30 হিসাবে , আপনি এটি করতে পারেন:

#!/usr/bin/env -S sed -f

এই বৈশিষ্ট্য একটি সাম্প্রতিক (2018-04-20) এ যোগ করা হয়েছিল কমিট করতে env.cগনুহ coreutils প্যাকেজ, যা যোগ মধ্যে -Sবা --split-stringবিকল্প।

থেকে envমানুষ পৃষ্ঠা:

OPTIONS
-S/--split-string usage in scripts
    The  -S  option allows specifing multiple parameters in a script.
    Running a script named 1.pl containing the following first line:

            #!/usr/bin/env -S perl -w -T

    Will execute perl -w -T 1.pl .

    Without the '-S' parameter the script will likely fail with:

            /usr/bin/env: 'perl -w -T': No such file or directory

    See the full documentation for more details.

আরও উদাহরণ জিএনইউ কোর্টিল ম্যানুয়ালটিতে পাওয়া যায়

আপনি যদি -vভার্বোস আউটপুট জন্য বিকল্পটি ব্যবহার করেন , আপনি ঠিক কীভাবে envআর্গুমেন্টের স্ট্রিংকে বিভক্ত করে তা দেখতে পারেন :

ইন my_sed_script.sed:

#!/usr/bin/env -vS sed -f
s/a/b/

এক্সেকিউশন:

$ ./my_sed_script.sed
split -S:  ‘sed -f’
 into:    ‘sed’
     &    ‘-f’
executing: sed
   arg[0]= ‘sed’
   arg[1]= ‘-f’
   arg[2]= ‘./my_sed_script.sed’

দ্রষ্টব্য: এটি কেবলমাত্র শেবাংগুলিতে প্রযোজ্য যা জিএনইউর বিশেষত বৈশিষ্ট্য /usr/bin/envহিসাবে ব্যবহার করে ।--split-stringenv


1

এই উত্তরটি একটি মার্জিত সমাধানের পথ সরবরাহ করে: /programming//a/1655389/642372

  1. read শেল ভেরিয়েবলের একটি হেরিডোক।
  2. স্থায়ী যুক্তি হিসাবে যে পরিবর্তনশীল পাস sed

নমুনা:

#!/usr/bin/env bash

read -rd '' SED_SCRIPT <<EOD      
# Your sed script goes here.
s/a/b/
EOD

exec sed "$SED_SCRIPT" "$@"

1

আমি ওয়াকারের সমাধানটি পছন্দ করি তবে এটি উন্নত করা যায় (এটিকে পৃথক উত্তরে রেখে দেওয়া কারণ মন্তব্যগুলি পূর্বরূপিত পাঠ্য গ্রহণ করে না)। এটি লিনাক্স বা ব্যাশের সমস্ত সংস্করণে কাজ নাও করতে পারে তবে উবুন্টু 17.10 এ আপনি নিম্নলিখিতটি কেটে ফেলতে পারেন:

#!/usr/bin/env bash
read SED_SCRIPT <<EOD
s/a/b/
EOD
sed "$SED_SCRIPT" "$@"

আপনি কমান্ডটি সরান evalএবং সরল করতে পারেন read, তবে আপনাকে হেরডকের ভিতরে থাকা মন্তব্য থেকে মুক্তি দিতে হবে।

এছাড়াও, যে কিছুর জন্য আপনি কখনও সেড সম্পর্কে জানতে চেয়েছিলেন কিন্তু জিজ্ঞাসা করতে ভয় পেয়েছিলেন তার জন্য, http://www.grymoire.com/unix/sed.html এ একটি খুব দরকারী টিউটোরিয়াল রয়েছে । এটি আরও উন্নততর সমাধানের প্রস্তাব দেয়, হারানোর /usr/bin/envএবং হার্ড কোডিংয়ের পথটি হারানোর ব্যয়ে :

#!/bin/sed -f
s/a/b/
s/c/d/

এটির একাধিক s///প্রতিস্থাপনকে সমর্থন করার অতিরিক্ত সুবিধা রয়েছে ।

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