সেড ব্যবহার করে দুটি স্ট্রিংয়ের সমস্ত উপস্থিতি পরিষ্কারভাবে অদলবদল করুন


13

ধরুন আমার কাছে এমন একটি ফাইল রয়েছে যাতে স্ট্রিংএ এবং স্ট্রিংবি উভয়ের একাধিক উপস্থিতি রয়েছে। আমি স্ট্রিংএ এর সমস্ত উপস্থিতি স্ট্রিংবি দিয়ে প্রতিস্থাপন করতে চাই, এবং (একসাথে) স্ট্রিংএ এর সাথে স্ট্রিংবি এর সমস্ত উপস্থিতি।

এখনই, আমি এরকম কিছু করছি

cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'

এই পদ্ধতির সমস্যাটি হ'ল এটি ধরে নেয় যে স্ট্রিংসি ফাইলটিতে ঘটে না। যদিও এটি বাস্তবে কোনও সমস্যা নয়, এই সমাধানটি এখনও নোংরা অনুভব করে - এটি, এটি আরও ইউনিক্স যাদু শেখার সুযোগ বলে মনে করে। :)

উত্তর:


11

যদি StringBএবং StringAএকই ইনপুট লাইনে উপস্থিত নাও হতে পারে তবে আপনি সেডটিকে প্রতিস্থাপনটি এক উপায়ে সম্পাদন করতে বলতে পারেন, এবং প্রথম অনুসন্ধানের স্ট্রিংয়ের কোনও উপস্থিতি না থাকলে কেবল অন্যভাবেই চেষ্টা করুন।

<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'

সাধারণ ক্ষেত্রে, আমি মনে করি না যে সেডের কোনও সহজ পদ্ধতি আছে। যাইহোক, নোট করুন যে স্পেসিফিকেশনটি অস্পষ্ট StringAএবং StringBযদি ওভারল্যাপ করতে পারে। এখানে একটি পার্ল সমাধান রয়েছে, যা উভয় স্ট্রিংয়ের বামতম ঘটনাকে প্রতিস্থাপন করে এবং পুনরাবৃত্তি করে।

<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
                    s/(StringA|StringB)/$r{$1}/ge'

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

<file.txt awk '{
    while (match($0, /StringA|StringB/)) {
        printf "%s", substr($0, 1, RSTART-1);
        $0 = substr($0, RSTART);
        printf "%s", /^StringA/ ? "StringB" : "StringA";
        $0 = substr($0, 1+RLENGTH)
    }
    print
}'

আমি যখন প্রথম কমান্ডটি চালাচ্ছি, সেড আমাকে বলে sed: can't read s/StringB/StringA/g: No such file or directory। এটা -e t PATTERNভাল বোঝা যায় না বলে মনে হচ্ছে।
গিসকোস

1
@ জিস্কোস -eদ্বিতীয় sকমান্ডের আগে নিখোঁজ ছিল । আমি আমার উত্তর স্থির করেছি।
গিলস 'অশুভ হওয়া বন্ধ করুন'

8

এই মুহুর্তে, আমি কিছু করছি
...............
এই পদ্ধতির সাথে সমস্যাটি এটি ধরে নেয় যে স্ট্রিংসি ফাইলটিতে ঘটে না occur

আমার ধারণা আপনার দৃষ্টিভঙ্গি ঠিক আছে, আপনার স্ট্রিংয়ের পরিবর্তে অন্য কিছু ব্যবহার করা উচিত, এমন কিছু যা একটি লাইনে ঘটে না (প্যাটার্ন স্পেসে)। সেরা প্রার্থী হ'ল \nইলাইন।
সাধারণত, প্যাটার্ন স্পেসের কোনও ইনপুট লাইন সেই অক্ষরটি ধারণ করে না, যাতে ফাইলের সমস্ত উপস্থিতি THISএবং অদলবদল THATকরতে আপনি চালাতে পারেন:

sed 's/THIS/\
/g
s/THAT/THIS/g
s/\n/THAT/g' infile

বা, যদি আপনার সেড \nআরএইচএসেও সমর্থন করে:

sed 's/THIS/\n/g;s/THAT/THIS/g;s/\n/THAT/g' infile

1
এটা সুন্দর. আমি একটু কেঁদেছি। আরএইচএস নিউলাইনগুলি করার আরেকটি উপায় হ'ল শেল ভেরিয়েবল - যদি সমর্থনগুলি sedনির্দিষ্টভাবে পালিয়ে যায় বা না হয় তবে আপনি যদি আগে থেকে কয়েকটি ম্যাক্রো প্রস্তুতি নেন তবে তা অনেক কম গুরুত্বপূর্ণ হয়ে ওঠে। যেমন set /THIS /THAT "$(printf \\n/)"; sed "s/$2/\\$4g;s/$3$2/g;s/\\n$3/g"- কিন্ডা বোকা এখানে, স্বীকারোক্তি সহকারে, তবে এটি যখন আরও কিছু সময় বিশেষত চর শ্রেণীর জন্য এবং একই রকমের হয় তখন এটি আরও বেশি অর্থবোধ করে।
মাইকসার্ভ

ঠিক আছে কিভাবে, মানুষ। এটি সম্পর্কে একটি উত্তর এমনকি আছে। আমি মন্তব্য করার সময় সেখানে ছিল? আমি সম্প্রতি জিনিসটি সম্পাদিত তালিকায় পপ আপ করতে দেখেছি (সম্ভবত) এবং শীর্ষ উত্তরের শীর্ষ লাইনটি কিছুটা বন্ধ ছিল (যদি আপনি কেবল এমবেডেড লিনাক্সের বিষয়ে চিন্তা করেন না, তবে আমার ধারণা) । আমি সেখানে গিলসের পরামর্শটিকে প্রাধান্য দিয়েছি - আপনি যদি দীর্ঘকালীন কাজ না করেন তবে sedধ্রুবক কাঁটাচামচ দিয়ে ওভারহেড eকিন্ডুভা দুঃস্বপ্ন। অন্য একটি নোটে - আমি pasteসারা দিন ধরে খেলছি । আমি একটি বিকল্প পার্সার তৈরি করেছি - যেমন column। এটি কেবল ইনপুট স্ট্রিং এবং স্ট্রিং স্টাফের জন্য একসাথে ড্যাশ জিন করে।
মাইক্রজারভ

3

আমি মনে করি এটি দুটি শব্দ অদলবদলের জন্য "ননস" স্ট্রিং ব্যবহার করা পুরোপুরি বৈধ। আপনি যদি আরও সাধারণ সমাধান চান তবে আপনি এর মতো কিছু করতে পারেন:

sed 's/_/__/g; s/you/x_x/g; s/me/you/g; s/x_x/me/g; s/__/_/g' <<<"say you say me"

যে ফলন

say me say you

নোট করুন যে আপনার x_xকাছে "x_x" স্ট্রিংগুলি ঘটতে থাকলে প্রতিস্থাপন এড়াতে আপনার দুটি অতিরিক্ত বিকল্প প্রয়োজন । তবে এটি এখনও awkআমার পক্ষে সমাধানের চেয়ে সহজ বলে মনে হচ্ছে ।


এটিকে দেখে মনে হচ্ছে যা তারা ইতিমধ্যে করছে।
রোয়াইমা

1
হ্যাঁ, আমি প্রথমে এটি উপেক্ষা করেছি (সম্পাদনার ইতিহাস দেখুন) তবে আমার প্রদত্ত সমাধানটি ভিন্ন কারণ যেহেতু প্রতিস্থাপন স্ট্রিং (এখানে "x_x") মূল স্ট্রিংয়ের ক্ষেত্রে ঘটে তখনও এটি আরও সাধারণ।
ডেভিড ওঙ্গারো

স্মার্ট, তবে একটা ধরা আছে। যদি স্ট্রিংএ বা স্ট্রিংবি থাকে _, তবে একটির _নিজের নিজেকে সামঞ্জস্য করতে হবে (অন্য একটি চরিত্র চয়ন করুন) বা ঝামেলাযুক্ত স্ট্রিং (এর s/_/__/gআগে এটি সম্পাদন করুন, আরও ভাল বলে মনে হচ্ছে)। আপনার সমাধানটি যেমন হয় তেমনি অন্বেষণ করে স্বেচ্ছাসেবী স্ট্র্যাপগুলিতে প্রয়োগ করা যায় না।
কামিল ম্যাকিয়েরোস্কি

নিবন্ধন করুন আমি আসলে s/_/__/gআগে থেকে আবেদন । হতে পারে কেবল একটি টেস্টকেস দেখান যা ব্যর্থ হয়।
ডেভিড ওঙ্গারো

@ কামিলম্যাসিওরওস্কি আহ আমি এখন বুঝতে পেরেছি বলে মনে করি। আপনি বলতে চাচ্ছেন যদি প্রতিস্থাপন স্ট্রিং নিজেই একটি ধারণ _, তাই প্রতিস্থাপন বলে y_ouসঙ্গে me। হ্যাঁ এটি সত্য যে এটি সম্পর্কে সচেতন হতে হবে এবং y__ouভাব প্রকাশ করতে হবে। কোনও স্ক্রিপ্ট যা প্রতিস্থাপনটিকে ইনপুট পরামিতি হিসাবে গ্রহণ করে তাও এটিকে অ্যাকাউন্টে নিতে হবে।
ডেভিড ওঙ্গারো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.