শ স্ক্রিপ্টে শেড ব্যবহার করার সময় আমার কোন চরিত্রগুলি পালাতে হবে?


248

নিম্নলিখিত স্ক্রিপ্ট নিন:

#!/bin/sh
sed 's/(127\.0\.1\.1)\s/\1/' [some file]

যদি আমি এটি sh( dashএখানে) চালানোর চেষ্টা করি তবে এটি প্রথম বন্ধনীগুলির কারণে ব্যর্থ হবে, যা এড়াতে হবে। কিন্তু আমি না ব্যাকস্ল্যাশ নিজেদের অব্যাহতি (অক্টেট মধ্যে, বা প্রয়োজন \sবা \1)। এখানে নিয়ম কি? আমার যখন ব্যবহার করা দরকার {...}বা তখন কী হবে [...]? আমি কী করি তার একটি তালিকা আছে এবং পালানোর দরকার নেই?


1
এসইডির সাথে ব্যবহারের জন্য পাথগুলি রূপান্তর করার জন্য এখানে একটি বাশ ফাংশন রয়েছে:function sedPath { path=$((echo $1|sed -r 's/([\$\.\*\/\[\\^])/\\\1/g'|sed 's/[]]/\[]]/g')>&1) } #Escape path for use with sed
ব্যবহারকার 2428118


ডুরা লেক্স, সেড সেড
নিমো

উত্তর:


281

এখানে ব্যাখ্যার দুটি স্তর রয়েছে: শেল এবং সেড।

শেলটিতে, একক উদ্ধৃতিগুলির মধ্যে থাকা সমস্ত কিছুই আক্ষরিক অর্থে ব্যাখ্যা করা হয়, কেবলমাত্র একক উদ্ধৃতিগুলি ব্যতীত। আপনার লিখিতভাবে একক উদ্ধৃতিগুলির মধ্যে কার্যকরভাবে একক উদ্ধৃতি থাকতে পারে '\''(একক উদ্ধৃতি বন্ধ করুন, একটি আক্ষরিক একক উদ্ধৃতি, একক উদ্ধৃতি খুলুন)।

শেড বেসিক নিয়মিত এক্সপ্রেশন ব্যবহার করে । একটি বিআরইতে, তাদের সাথে আক্ষরিক আচরণ করার জন্য, অক্ষরগুলির $.*[\^অভ্যন্তরের অক্ষর সেটগুলি ( […]) বাদ দিয়ে ব্যাকস্ল্যাশ করে তার আগে অক্ষরগুলি উদ্ধৃত করা প্রয়োজন । চিঠিগুলি, অঙ্কগুলি এবং (){}+?|উদ্ধৃত হওয়া আবশ্যক নয় (কিছু বাস্তবায়নের ক্ষেত্রে এইগুলির কয়েকটি উদ্ধৃত করে আপনি পালাতে পারেন)। সিকোয়েন্স \(, \), \n, এবং কিছু বাস্তবায়নের মধ্যে \{, \}, \+, \?, \|এবং অন্যান্য ব্যাকস্ল্যাশ + + কারাকাস বিশেষ অর্থ আছে। $^কিছু বাস্তবায়নে কিছু পদে উদ্ধৃতি না দিয়ে আপনি পালাতে পারেন ।

তদ্ব্যতীত, /যদি এটি বন্ধনী এক্সপ্রেশন এর বাইরের রেজেক্সে উপস্থিত হয় তবে আপনাকে আগে একটি ব্যাকস্ল্যাশ দরকার । আপনি লেখার মাধ্যমে ডিলিমিটার হিসাবে একটি বিকল্প চরিত্র চয়ন করতে পারেন, উদাহরণস্বরূপ, s~/dir~/replacement~বা \~/dir~p; আপনি যদি এটিকে বিআরএতে অন্তর্ভুক্ত করতে চান তবে আপনার ডিলিমিটারের আগে একটি ব্যাকস্ল্যাশ লাগবে। আপনি যদি এমন একটি চরিত্র চয়ন করেন যা একটি বিআরইতে একটি বিশেষ অর্থ রয়েছে এবং আপনি এটি আক্ষরিকভাবে অন্তর্ভুক্ত করতে চান তবে আপনার তিনটি ব্যাকস্ল্যাশ দরকার হবে; আমি এটির প্রস্তাব দিচ্ছি না, কারণ এটি কিছু বাস্তবায়নে আলাদা আচরণ করতে পারে।

সংক্ষেপে, এর জন্য sed 's/…/…/':

  • একক উদ্ধৃতিগুলির মধ্যে রেজেক্স লিখুন।
  • '\''রেজেক্সে একক উদ্ধৃতি দিয়ে শেষ করতে ব্যবহার করুন ।
  • একটি ব্যাকস্ল্যাশ আগে রাখুন $.*/[\]^এবং কেবলমাত্র সেই অক্ষরগুলি (তবে ব্র্যাকেট প্রকাশের ভিতরে নয়)। (প্রযুক্তিগতভাবে আপনার আগে কোনও ব্যাকস্ল্যাশ লাগানো উচিত নয় ]তবে আমি এমন একটি বাস্তবায়ন সম্পর্কে জানি না যা ব্র্যাককেট এক্সপ্রেশনগুলির বাইরে আচরণ করে ]এবং \]আলাদাভাবে।
  • -আক্ষরিক অর্থে চিকিত্সা করার জন্য একটি বন্ধনী প্রকাশের ভিতরে , নিশ্চিত করুন যে এটি প্রথম বা শেষ ( [abc-]বা [-abc]না [a-bc])।
  • ^আক্ষরিকভাবে চিকিত্সা করার জন্য একটি বন্ধনী প্রকাশের ভিতরে , নিশ্চিত হয়ে নিন যে এটি প্রথম নয় (ব্যবহার করুন [abc^], না [^abc])।
  • ]বন্ধনীর অক্ষর দ্বারা মিলিত অক্ষরের তালিকায় অন্তর্ভুক্ত করার জন্য, এটি প্রথম অক্ষর (বা ^অবহেলিত সেট পরে প্রথম ): []abc]বা [^]abc](নয় ) [abc]]nor[abc\]]

প্রতিস্থাপন পাঠ্যে:

  • &এবং \ডিলিমিটার (সাধারণত /) এবং নিউলাইনগুলিতে যেমন ব্যাকস্ল্যাশ করে সেগুলি আগে রেখে উদ্ধৃত করা দরকার ।
  • \অঙ্কের পরে একটি বিশেষ অর্থ রয়েছে। \কিছু বাস্তবায়নের পরে একটি চিঠির একটি বিশেষ অর্থ (বিশেষ অক্ষর) থাকে এবং এর \পরে কিছু অন্যান্য চরিত্রের অর্থ হয় \cবা cপ্রয়োগের উপর নির্ভর করে।
  • আর্গুমেন্ট ( sed 's/…/…/') এর চারপাশে একক উদ্ধৃতি সহ , '\''প্রতিস্থাপন পাঠ্যে একক উদ্ধৃতি রাখতে ব্যবহার করুন।

যদি রেজেক্স বা প্রতিস্থাপন পাঠ্যটি শেল ভেরিয়েবল থেকে আসে তবে এটি মনে রাখবেন

  • রেজেক্স একটি বিআরই, আক্ষরিক স্ট্রিং নয়।
  • রেজেক্সে একটি নতুনলাইন হিসাবে প্রকাশ করা দরকার \n( sedপ্যাটার্ন স্পেসে নতুন লাইন অক্ষর যুক্ত না করে অন্য কোডটি মিলবে না যা কখনই মিলবে না )। তবে মনে রাখবেন যে এটি কিছু sedবাস্তবায়ন সহ বন্ধনী প্রকাশের ভিতরে কাজ করবে না ।
  • প্রতিস্থাপন লেখা, &, \এবং নতুন লাইন উদ্ধৃত করা প্রয়োজন।
  • ডিলিমিটারটি উদ্ধৃত করা প্রয়োজন (তবে বন্ধনী প্রকাশের ভিতরে নয়)।
  • ক্ষেপক জন্য ডবল কোট ব্যবহার করুন: sed -e "s/$BRE/$REPL/"

আসল ওয়াইল্ডকার্ড অক্ষর (*) এড়িয়ে চলে আপনি ডাবল ব্যাকস্ল্যাশ ( \\*) ব্যবহার করতে পারেন । উদাহরণ:echo "***NEW***" | sed /\\*\\*\\*NEW\\*\\*\\*/s/^/#/
বিপদ 89

43

আপনি যে সমস্যাটি ভোগ করছেন তা শেল ইন্টারপোলটিং এবং পলায়নের কারণে নয় - এর কারণ আপনি সেড -rবা --regexp-extendedবিকল্পটি পাস না করে প্রসারিত নিয়মিত এক্সপ্রেশন সিনট্যাক্স ব্যবহার করার চেষ্টা করছেন ।

এ থেকে আপনার এসড লাইনটি পরিবর্তন করুন

sed 's/(127\.0\.1\.1)\s/\1/' [some file]

প্রতি

sed -r 's/(127\.0\.1\.1)\s/\1/' [some file]

আপনার বিশ্বাস হিসাবে আমি বিশ্বাস করি এটি কাজ করবে।

ডিফল্টরূপে সেড বেসিক নিয়মিত এক্সপ্রেশন ব্যবহার করে (গ্রেপ স্টাইল ভাবেন) ব্যবহার করে, যার জন্য নিম্নলিখিত সিনট্যাক্সের প্রয়োজন হবে:

sed 's/\(127\.0\.1\.1\)[ \t]/\1/' [some file]

আমার আবার এই সমস্যা হয়েছিল, এবং আমি শেষবারের মতো উত্থাপিত সমাধানটি অনুসন্ধান করতে ভুলে গিয়েছিলাম। আবার ধন্যবাদ.
isaaclw

অনেক ধন্যবাদ. -rবিকল্প হিসাবে যুক্ত করা আমার ক্ষেত্রে প্রয়োজনীয় ছিল।
হ্যালো গুডবাই

15

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

সুতরাং যদি আপনি এর s/\(127\.0\.1\.1\)\s/\1/চারপাশে একক উদ্ধৃতিগুলি রাখার জন্য সেড চান এবং শেলটি এতে প্রথম বন্ধনী বা ব্যাকস্ল্যাশগুলি স্পর্শ করবে না। যদি আপনার শেল ভেরিয়েবলটি ইন্টারপল্ট করতে হয় তবে কেবলমাত্র সেই অংশটি ডাবল উদ্ধৃতিতে রাখুন। যেমন

sed 's/\(127\.0\.1\.1\)/'"$ip"'/'

এটি কোন শেল মেটাচার্যাক্টরের দ্বিগুণ উদ্ধৃতি দ্বারা রক্ষা পায় তা মনে করার ঝামেলা বাঁচাবে।


আমি sedদেখতে চাই s/(127\.0\.1\.1)/..., তবে শেল স্ক্রিপ্টে যেমন রাখা তেমন কার্যকর হয় না। বন্ধনী স্পর্শ না করে আপনি শেল সম্পর্কে যা বলছেন তা ভুল বলে মনে হচ্ছে। আমি আমার প্রশ্নটি বিস্তারিতভাবে সম্পাদনা করেছি।
অবধি

3
শেলটি প্রথম বন্ধনী স্পর্শ করছে না। আপনার ব্যাকস্লেসগুলি প্রয়োজন কারণ সেডগুলি তাদের দেখতে হবে। sed 's/(127\.0\.1\.1)/IP \1/'ব্যর্থ হয় কারণ সেড দেখতে \(এবং \)গ্রুপ সিনট্যাক্সের জন্য প্রয়োজন , (এবং নয় )
কাইল জোন্স

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

3
Traditionalতিহ্যবাহী ইউনিক্স কমান্ডগুলির জন্য, এখানে বেসিক নিয়মিত এক্সপ্রেশন এবং বর্ধিত নিয়মিত এক্সপ্রেশন রয়েছে। বিশদ । সেড বেসিক নিয়মিত এক্সপ্রেশন ব্যবহার করে, সুতরাং গ্রুপ সিনট্যাক্সের জন্য ব্যাকস্ল্যাশগুলি প্রয়োজন। পার্ল এবং পাইথন এমনকি বর্ধিত নিয়মিত অভিব্যক্তি ছাড়িয়ে গেছে। আমি যখন ঘুরে বেড়াচ্ছিলাম তখন আমি একটি অত্যন্ত তথ্যবহুল চার্ট পেলাম যা চিত্রিত করে যে আমরা যখন ঝর্ণা দিয়ে বলি "নিয়মিত প্রকাশ" up
কাইল জোন্স

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