কীভাবে নিশ্চিত করা যায় যে স্ট্রিংটি বিভক্তভাবে `সেড-প্রতিস্থাপনে বিভক্ত হয়ে সমস্ত মেটাচর থেকে পালিয়ে যায়


21

আমার কাছে একটি স্ক্রিপ্ট রয়েছে যা একটি পাঠ্য স্ট্রিম পড়ে এবং সেড কমান্ডগুলির একটি ফাইল উত্পন্ন করে যা পরে চালানো হয় sed -f। উত্পাদিত সেড কমান্ডগুলি হ'ল:

s/cid:image002\.gif@01CC3D46\.926E77E0/https:\/\/mysite.com\/files\/1922/g
s/cid:image003\.gif@01CC3D46\.926E77E0/https:\/\/mysite.com\/files\/1923/g
s/cid:image004\.jpg@01CC3D46\.926E77E0/https:\/\/mysite.com\/files\/1924/g

ধরে নিন যে স্ক্রিপ্ট যা sedকমান্ড উত্পন্ন করে তা হ'ল:

while read cid fileid
do
    cidpat="$(echo $cid | sed -e s/\\./\\\\./g)"
    echo 's/'"$cidpat"'/https:\/\/mysite.com\/files\/'"$fileid"'/g' >> sedscr
done

cidস্ট্রিংয়ের সমস্ত রেজেক্স মেটাচার্যাকারগুলি পালানো এবং সঠিকভাবে ইন্টারপোল্ট করা হয়েছে তা নিশ্চিত করতে আমি কীভাবে স্ক্রিপ্টটি উন্নত করতে পারি ?

উত্তর:


24

(এখানে এবং যথাক্রমে) sকমান্ডের বাম দিকে এবং ডানদিকে ব্যবহার করার জন্য ভেরিয়েবলগুলি এড়ানোর জন্য , আপনি:sed$lhs$rhs

escaped_lhs=$(printf '%s\n' "$lhs" | sed 's:[][\/.^$*]:\\&:g')
escaped_rhs=$(printf '%s\n' "$rhs" | sed 's:[\/&]:\\&:g;$!s/$/\\/')

sed "s/$escaped_lhs/$escaped_rhs/"

মনে রাখবেন যে $lhsএকটি নতুন লাইন অক্ষর থাকতে পারে না।

অর্থাৎ, এলএইচএসে, সমস্ত রেজিপ্সেপ অপারেটরগুলি ( ][.^$*), পালিয়ে যাওয়া চরিত্র নিজেই ( \) এবং বিভাজক ( /) এড়িয়ে চলুন ।

আরএইচএসে আপনাকে কেবল পালাতে হবে &, বিভাজক, ব্যাকস্ল্যাশ এবং নিউলাইন চরিত্রটি (যা আপনি সর্বশেষটি ( $!s/$/\\/) বাদে প্রতিটি লাইনের শেষে একটি ব্যাকস্ল্যাশ সন্নিবেশ করিয়েছেন )।

যা আপনি ব্যবহার অনুমান /আপনার একটি বিভাজক হিসেবে sed sকমান্ড এবং আপনি সক্ষম করবেন না যে এক্সটেন্ডেড মাঝামাঝি সঙ্গে -r(গনুহ sed/ ssed/ ast/ busybox sed) অথবা -E(BSD গুলোর, astসাম্প্রতিক গনুহ, সাম্প্রতিক, busybox) অথবা PCREs সঙ্গে -R( ssed) অথবা বৃদ্ধি মাঝামাঝি সঙ্গে -A/ -X( ast) যা সবার অতিরিক্ত আরআর অপারেটর রয়েছে।

যথেচ্ছ ডেটা নিয়ে কাজ করার সময় কয়েকটি স্থল নিয়ম:

  • ব্যবহার করবেন না echo
  • আপনার পরিবর্তনশীল উদ্ধৃতি
  • লোকেলের প্রভাব বিবেচনা করুন (বিশেষত এর চরিত্রের সেট: উদাহরণস্বরূপ পলায়নকারী স্ট্রিংগুলি (এবং একই কমান্ডের সাহায্যে) কমান্ডের মতো একই লোকেলে পালানো sed কমান্ডগুলি চালানো গুরুত্বপূর্ণ )sedsed
  • নতুন লাইন চরিত্রটি সম্পর্কে ভুলবেন না (এখানে আপনি $lhsকোনও রয়েছে কিনা তা পরীক্ষা করে নিতে এবং পদক্ষেপ নিতে চাইতে পারেন)।

আর একটি বিকল্প হ'ল পরিবেশে স্ট্রিংগুলির perlপরিবর্তে ব্যবহার sedএবং পাস করা এবং আক্ষরিকভাবে স্ট্রিং নেওয়ার জন্য \Q/ \E perlregexp অপারেটরগুলি ব্যবহার করা:

A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'

perl(ডিফল্টরূপে) লোকালের চরিত্রটি দ্বারা প্রভাবিত হবে না উপরের হিসাবে, এটি কেবল স্ট্রিংগুলিকে বাইটের অ্যারে হিসাবে বিবেচনা করে না তারা কোন অক্ষর (যদি থাকে) সেগুলি ব্যবহারকারীর জন্য উপস্থাপন করতে পারে about সঙ্গে sed, আপনি লোকেল ফিক্সিং একই অর্জন করতে পারে Cসঙ্গে LC_ALL=Cসব জন্য sedকমান্ড (যদিও যে যদি থাকে, ত্রুটি বার্তা ভাষা প্রভাবিত করবে)।


আমার যদি ডাবল উক্তি থেকে বাঁচার দরকার হয়?
মেনন

@ মেনন, ডাবল উক্তিগুলি বিশেষ নয় sed, আপনার এড়াতে হবে না।
স্টাফেন চেজেলাস

এটি ওয়াইল্ডকার্ড ব্যবহার করে প্যাটার্ন ম্যাচের জন্য ব্যবহার করা যাবে না, তাই না?
মেনন

@Menon, না, ওয়াইল্ডকার্ড প্যাটার্ন ম্যাচিং সঙ্গে find'গুলি -nameরেগুলার এক্সপ্রেশনের থেকে আলাদা। সেখানে আপনাকে কেবল পালাতে হবে ?, *ব্যাকস্ল্যাশ করতে হবে এবং[
স্টাফেন চ্যাজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.