সেডে একাধিক পুনঃব্যবহারের জন্য আপনি কীভাবে একটি জটিল রেজেক্স সংরক্ষণ করবেন?


12

ব্যবহার করার সময় sed, আমি প্রায়শই বরং জটিল এবং জটিল জটিল রেজেক্স তৈরি করি যা একটি ফাইলের সাথে আমার দু'বার মেলাতে হবে। আমার কাছে এই রেজেক্সকে বাঁচানোর এবং কেবল দু'বার রেফারেন্স করার কোনও উপায় আছে?

এমন কিছু মনে হচ্ছে?

sed ' complicated_regex=/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/
s/complicated_regex:complicated_regex/simple-output/
' my_file

আপডেট: একটি উত্তর একটি ব্যাশ ভেরিয়েবল ব্যবহারের সমাধান উপস্থাপন করেছে। এটি কাজ করে না। দেওয়া a test.txt

#test.txt
foo bar
bar foo

এবং স্ক্রিপ্ট

#!/bin/bash

VALUE='foo \([a-z]\+\)'

sed 's/"${VALUE}"/foo happy \1/' test.txt

এটি আউটপুট উত্পাদন করা উচিত

foo happy bar
bar foo

তবে পরিবর্তে আমি ত্রুটি পেয়েছি

sed: -e expression #1, char 24: invalid reference \1 on `s' command's RHS

আপনি যদি পার্ল ব্যবহার করেন তবে আপনি প্রকাশের পূর্বের অংশগুলি উল্লেখ করতে পারেন:perl -pe 's/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+:\1$/simple_output/' my_file
গ্লেন জ্যাকম্যান

1
আপনি যখন শেডের জন্য খুব জটিল কিছু আবিষ্কার করেন, তখন অবাস্তব বা পার্ল যেতে দ্বিধা করবেন না।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

2
@ কোরি: আপনার উদাহরণটি সঠিকভাবে কাজ করে, যদি আপনি এর বাক্য গঠনটি সঠিকভাবে পান। আপনার কাছে "$ ভেরিয়েবল" এখনও 'সিঙ্গল- sed 's/'"${VALUE}"'/foo happy \1/' test.txt
কোটস'

উত্তর:


7

আপনি শেল ভেরিয়েবল ব্যবহার করতে পারেন:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

আপনি কী বোঝাতে চেয়েছেন তা সম্পর্কে আমি নিশ্চিত নই $i, তবে আপনাকে এটি একক উদ্ধৃতিগুলির বাইরে রাখতে হবে:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'

অবশ্যই এটি কাজ করে যদি sedশেল থেকে কমান্ডটি চাওয়া হয় তবে প্রায় সমস্ত প্রোগ্রামিং ভাষার সাথে একই রকম সমাধান রয়েছে। (এবং এর মধ্যে ভেরিয়েবলগুলি ব্যবহার করা সম্ভব বলে আমি মনে করি না sed))
স্টাফেন গিমেনেজ

এইচআরএম। এটি চেষ্টা করে, পিছনে উল্লেখগুলি ভঙ্গ হয়ে গেছে বলে মনে হচ্ছে। s/$complicated_regex/\1/এটি একটি অবৈধ রেফারেন্স বলে ত্রুটি দেয়।
Cory Klein

আহ, সম্ভবত আমার দোষ, আমি ভেরিয়েবল বিকল্পগুলি zsh করতে অভ্যস্ত। আপডেট উত্তর দেখুন।
স্টাফেন গিমেনেজ

আপনাকে পরিবর্তনশীল থেকে অ্যাঙ্করগুলি সরিয়ে sed "s/^${complicated_regex}:${complicated_regex}\$/simple-output/" my_file
সেড

Duh! হ্যাঁ, আমি যাচাই করতে ভুলে গেছি যে আমাকে একটি বৈধ রেইগেক্স কনটেনটেশন প্রদান করা হয়েছে :-)
স্টাফেন গিমেনেজ

0

sedআপনার ব্যাকস্ল্যাশ-পলায়নের জন্য আপনার sedস্ক্রিপ্টের বাকী অংশের জন্য কীভাবে পরিবর্তন প্রয়োজন হবে তা নিয়ে চিন্তিত না হওয়ার সবচেয়ে সহজ উপায় হ'ল ভেরিয়েবল ব্যতীত একক উদ্ধৃতিতে সমস্ত কিছু স্টাফ করা এবং ডাবল উদ্ধৃতিতে রাখুন।

নিম্নলিখিত কোডের সমস্ত উদাহরণ ধরে নেওয়া: VALUE='foo \([a-z]\+\)'

নিম্নলিখিত ভগ্ন কোডটি ব্যর্থ হয়েছে কারণ ভেরিয়েবলটি VALUEপ্রসারিত হয়নি:

sed 's/"${VALUE}"/foo happy \1/' test.txt

নিম্নলিখিত ভাঙা কোডটি ব্যর্থ হয়েছে কারণ এর আগে ব্যাকস্ল্যাশটি \1শেলটি খেয়ে ফেলেছে (কারণ এটি একক উদ্ধৃতিগুলির চেয়ে ডাবল কোটের মধ্যে রয়েছে) এটি দেখার আগে sed:

sed "s/${VALUE}/foo happy \1/" test.txt

নিম্নলিখিত কোডটি প্রত্যাশার মতো কাজ করে:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

থো নিম্নলিখিত কোডগুলিও কাজ করে:

sed "s/${VALUE}/foo happy \\1/" test.txt

নিম্নলিখিতগুলিও তাই করে:

sed s/"${VALUE}"/foo\ happy\ \\1/ test.txt

তবে কেন জটিল? কোনও sedস্ক্রিপ্টের একক উদ্ধৃতি সমস্ত কিছুকে আরও পরিষ্কার করে তোলে, বিশেষত নন-শেল-স্ক্রিপ্টিং-গুরুদের জন্য আপনার কোডটি পড়া reading আমার পছন্দসই উপায়টি আবার, কেবলমাত্র ভেরিয়েবল প্রসারণের জন্য একক উদ্ধৃতি থেকে ডাবল উদ্ধৃতি ছেড়ে এবং একক উদ্ধৃতিতে সরাসরি ফিরে যেতে:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.