কমান্ড-লাইনে রেগেক্স ব্যাকস্ল্যাশ থেকে মুক্তির জন্য প্রয়োজনীয় ব্যাকস্ল্যাশগুলির সংখ্যা


12

কমান্ড-লাইনে সম্প্রতি কিছু রেইগেক্স নিয়ে আমার সমস্যা হয়েছিল এবং আমি খুঁজে পেয়েছি যে ব্যাকস্ল্যাশ মিলানোর জন্য বিভিন্ন সংখ্যক অক্ষর ব্যবহার করা যেতে পারে। এই সংখ্যাটি রেজেক্সের জন্য ব্যবহৃত উদ্ধৃতিগুলির উপর নির্ভর করে (কোনওটিই নয়, একক উদ্ধৃতি, ডাবল উদ্ধৃতি)। আমার অর্থের জন্য নিম্নলিখিত বাশ সেশনটি দেখুন:

echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file

এই যে মানে:

  • কোনও উদ্ধৃতি ছাড়াই, আমি 4-7 আসল ব্যাকস্ল্যাশ সহ একটি ব্যাকস্ল্যাশ মেলাতে পারি
  • ডাবল উদ্ধৃতি সহ, আমি 3-6 প্রকৃত ব্যাকস্ল্যাশগুলির সাথে একটি ব্যাকস্ল্যাশ মেলাতে পারি
  • একক উদ্ধৃতি সহ, আমি 2-3 টি আসল ব্যাকস্ল্যাশ সহ একটি ব্যাকস্ল্যাশ মেলাতে পারি

আমি বুঝতে পারি যে একটি অতিরিক্ত ব্যাকস্ল্যাশ শেল দ্বারা উপেক্ষা করা হবে (ব্যাশ ম্যান পৃষ্ঠা থেকে):

"একটি অ-উদ্ধৃত ব্যাকস্ল্যাশ (\) হ'ল পালাবার চরিত্র It এটি পরবর্তী অক্ষরের আক্ষরিক মান সংরক্ষণ করে যা অনুসরণ করে"

এটি একক-উদ্ধৃত উদাহরণগুলিতে প্রযোজ্য নয়, কারণ একক উদ্ধৃতিতে কোনও পলায়ন করা হয় না।

এবং আরও একটি অতিরিক্ত ব্যাকস্ল্যাশ গ্রেপ কমান্ড দ্বারা উপেক্ষা করা হয় ("\ সি" কেবল "সি" পালিয়ে গেছে, তবে এটি "সি" এর মতোই, কারণ "গ" এর একটি রেজেক্সের বিশেষ অর্থ নেই)।

এটি একক উদ্ধৃতি দিয়ে উদাহরণের আচরণ ব্যাখ্যা করে, তবে আমি অন্য দুটি উদাহরণ সত্যই বুঝতে পারি না, বিশেষত কেন নন-কউটেড একটি ডাবল-কোটেড স্ট্রিংয়ের মধ্যে পার্থক্য রয়েছে।

আবার, বাশ ম্যান পৃষ্ঠা থেকে একটি উদ্ধৃতি:

"ডাবল উক্তিগুলিতে অক্ষরগুলি সংযুক্ত করা $,`, \, এবং, যখন ইতিহাসের প্রসারণ সক্ষম করা হয়, ব্যতীত উদ্ধৃতিগুলির মধ্যে সমস্ত অক্ষরের আক্ষরিক মান সংরক্ষণ করে! "

আমি জিএনইউ অ্যাজকে (যেমন awk /ab\cd/{print} file) একই ফলাফল দিয়ে একই চেষ্টা করেছি।

পার্ল, তবে, বিভিন্ন ফলাফল দেখায় (উদাহরণস্বরূপ perl -ne "/ab\\cd/"\&\&print file):

  • কোনও উদ্ধৃতি ছাড়াই, আমি 4-5 আসল ব্যাকস্ল্যাশ সহ একটি ব্যাকস্ল্যাশ মেলাতে পারি
  • ডাবল উদ্ধৃতি সহ, আমি 3-4 আসল ব্যাকস্ল্যাশ সহ একটি ব্যাকস্ল্যাশ মেলাতে পারি
  • একক উদ্ধৃতি সহ, আমি 2 টি আসল ব্যাকস্ল্যাশ সহ একটি ব্যাকস্ল্যাশ মেলাতে পারি

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

উত্তর:


10

অকেজো উদাহরণের জন্য, প্রতিটি \\জুড়ি একটি ব্যাকস্ল্যাশ গ্রেপকে পাস করে, সুতরাং 4 ব্যাকস্ল্যাশ দুটি গ্রেপ থেকে পাস করে, যা একক ব্যাকস্ল্যাশকে অনুবাদ করে। 6 ব্যাকস্ল্যাশ তিনটি গ্রেপ থেকে পাস করে, একটি ব্যাকস্ল্যাশ এবং একটিতে অনুবাদ করে \cযা সমান c। একটি অতিরিক্ত ব্যাকস্ল্যাশ কিছু পরিবর্তন করে না, কারণ এটি অনুবাদ করা হয় \c-> cশেল দ্বারা। শেলের আটটি ব্যাকস্ল্যাশ চারটি গ্রেপ, দুটিতে অনুবাদ, সুতরাং এটি আর মেলে না।

ডাবল উক্তিগুলির উদাহরণের জন্য, ব্যাশ ম্যানপেজ থেকে আপনার দ্বিতীয় উদ্ধৃতিটি কী অনুসরণ করে তা নোট করুন:

ব্যাকস্ল্যাশ কেবল তখনই এর বিশেষ অর্থ ধরে রাখে যখন নিম্নলিখিত অক্ষরের একটি অনুসরণ করা হয়: $, `,",।, বা নিউলাইন।

উদাহরণস্বরূপ, আপনি যখন একটি বিচিত্র সংখ্যক ব্যাকস্ল্যাশ প্রদান করেন, ক্রমটি শেষ হয় \cযা cঅব্যক্ত ক্ষেত্রে সমান হবে তবে উদ্ধৃত করা হলে ব্যাকস্ল্যাশটির বিশেষ অর্থটি হারিয়ে যায়, তাই গ্রেপকে \cদেওয়া হয়। এ কারণেই "সম্ভাব্য" ব্যাকস্ল্যাশগুলির পরিসর (যেমন আপনার উদাহরণের ফাইলের সাথে মেলে এমন একটি প্যাটার্ন তৈরি করে) একের পর এক স্লাইড হয়।


... এবং তারপরে কিছু অদ্ভুততা রয়েছে: উদাহরণস্বরূপ: printf "\ntest""পরীক্ষার" আগে একটি নতুন লাইন প্রবেশ করানো হবে, যদিও শেলের দ্বারা এটি "\n"অনুবাদ করা উচিত ছিল "n"যেমন এটি দ্বিগুণ উদ্ধৃতি হিসাবে রয়েছে ... (সুতরাং প্রত্যাশিত ফলাফলটি হওয়া উচিত, "test নিস্ট", "নেস্ট" We আমাদের লেখার অভ্যাস করা উচিত: printf "\\ntest"বা printf '\ntest', তবে কোনওরকমভাবে আমি এর পরিবর্তে অদ্ভুততার উপরে অনেক স্ক্রিপ্ট নির্ভর করে দেখছি
অলিভিয়ার ডুলাক

6

এই লিঙ্কটিতে ব্যাশ কোটস এবং এসকেপিংয়ের বর্ণনা রয়েছে

আপনার প্রশ্ন প্রথম তিনটি বিভাগ নিয়ে কাজ করে।

  • পার-চরিত্রের অব্যাহতি
  • দুর্বল উদ্ধৃতি "ডাবল উদ্ধৃতি"
  • শক্তিশালী উদ্ধৃতি 'একক উদ্ধৃতি'
  • এএনএসআই সি স্ট্রিং কোটিংয়ের মতো
  • আই 18 এন / এল 10 এন উদ্ধৃতি (আন্তর্জাতিকীকরণ এবং স্থানীয়করণ)

নীচে স্ট্রিংগুলি কীভাবে bashতাদের উপর চলে যায় grepএবং কীভাবে grepআরও অভ্যন্তরীণভাবে সেগুলি ব্যাখ্যা করে তার একটি চার্ট দেওয়া আছে ।

প্রথমে তাকান echo "#ab\\cd" > file
ইন দুর্বল-উদ্ধৃত ( "") "#ab\\cd", \\একটি পলান হয় \যা পাস করা হয়েছে fileএকটি একক আক্ষরিক যেমন \। সুতরাং, fileরয়েছে ab\cd

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

ব্যাকস্ল্যাশ কেবল তখনই এর বিশেষ অর্থ ধরে রাখে যখন নিম্নলিখিত অক্ষরের একটি অনুসরণ করা হয়: $, `,",।, বা নিউলাইন।


                            bash passes    grep further
                            to grep        resolves to         
grep -E ab\cd file            abcd           abcd   
grep -E ab\\cd file           ab\cd          abcd  
grep -E ab\\\cd file          ab\cd          abcd
grep -E ab\\\\cd file         ab\\cd         ab\cd    * 
grep -E ab\\\\\cd file        ab\\\cd        ab\cd    *
grep -E ab\\\\\\cd file       ab\\\cd        ab\cd    *    
grep -E ab\\\\\\\cd file      ab\\\cd        ab\cd    *
grep -E ab\\\\\\\\cd file     ab\\\\cd       ab\\cd

grep -E "ab\cd" file          ab\cd          abcd
grep -E "ab\\cd" file         ab\cd          abcd
grep -E "ab\\\cd" file        ab\\cd         ab\cd    *
grep -E "ab\\\\cd" file       ab\\cd         ab\cd    *
grep -E "ab\\\\\cd" file      ab\\\cd        ab\cd    *
grep -E "ab\\\\\\cd" file     ab\\\cd        ab\cd    *
grep -E "ab\\\\\\\cd" file    ab\\\\cd       ab\\cd    

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