কেন `সেড এক্সপ্রেস 1 | exp sed -e expr1 -e expr2` এর থেকে আলাদা আলাদা আলাদা sed


10

আমি যে idগ্রুপগুলির মধ্যে একজন সদস্য সেগুলির আরও পঠনযোগ্য লাইন-বাই-তালিকার তালিকা সরবরাহ করতে আউটপুটটি বিভক্ত করছি :

id roaima | sed 's/,/\n\t/g'
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima)
    24(cdrom)
    25(floppy)
    ...
    822413650 (international (uk) location)

আমি গ্রুপ নম্বরটি এর বন্ধনীযুক্ত নাম থেকে আলাদা করতে চেয়েছিলাম তাই আমি এই মতটি প্রকাশ করেছি

id roaima | sed -e 's/,/\n\t/g' -e '2,$s/(/ (/'

যাইহোক, এটি প্রাথমিকভাবে আমার প্রত্যাশা মতো কাজ করে নি। দ্বিতীয় প্রকাশটির কোনও প্রভাব নেই বলে মনে হয়েছিল।

পরিবর্তে, আমি যে ফলাফলটি চেয়েছিলাম তা পেতে, আমাকে দুটি পৃথক sedকমান্ড চালানো দরকার :

id roaima | sed -e 's/,/\n\t/g' | sed '2,$s/(/ (/'
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima)
    24 (cdrom)
    25 (floppy)
    ...
    822413650 (international (uk) location)

কেন sedপাইপটিতে একাধিক নির্দেশাবলীর চেয়ে দুটি কমান্ডের প্রয়োজন ? বা আমি যদি এটির সাথে এটি করতে পারি তবে আমি sedকীভাবে এটি করব?

আমি বিশেষত যা চাই তা হ'ল প্রতিটি আইটেমের জন্য ইউআইডি / জিআইডি মান এবং এর বন্ধনীযুক্ত নামের (প্রথম লাইনে থাকা ইউআইডি এবং জিআইডি সহ) একক স্থান থাকতে পারে, তবে সতর্কতাইটি হ'ল আমার আসল তথ্যগুলিতে আমার গ্রুপ থাকতে পারে তাদের নামগুলিতে বন্ধনী রয়েছে এবং আমি নামগুলি নিজেরাই ম্যাঙ্গেল করতে চাই না।

উত্তর:


14

sedমত awkবা cutবা perl -neপ্রতিটি লাইনে কাজ করে স্বতন্ত্রভাবে একের পর এক।

sed -e code1 -e code2

আসলে চালানো হয়:

while(patternspace = getline()) {
  linenumber++
  code1
  code2
} continue {print patternspace}

যদি আপনার কোড 2 হয় তবে 2,$ s/foo/bar/তা:

if (linenumber >= 2) sub(/foo/, "bar", patternspace)

আপনার ইনপুটটিতে কেবল একটি লাইন থাকায়, sub()কখনই চালানো হবে না।

প্যাটার্ন স্থান সম্পর্কে newline অক্ষর সন্নিবেশ করানো হচ্ছে মধ্যে code1দেখা যায় না linenumberবৃদ্ধি।

পরিবর্তে, ইনপুটটির প্রথম এবং একমাত্র লাইনটি প্রক্রিয়া করার সময় আপনার কয়েকটি রেখার সাথে এক প্যাটার্ন স্পেস রয়েছে । আপনি যদি সেই মাল্টি-লাইন প্যাটার্ন স্পেসের দ্বিতীয় লাইনে এবং তার চেয়ে বেশি সংশোধন করতে চান তবে আপনার যেমন কিছু করতে হবে:

s/\(\n[^(]*\)(/\1 (/g

যদিও এখানে অবশ্যই, আপনি পাশাপাশি দুটি পরিচালনা করতে পারেন একযোগে:

id | sed 's/,\([^(]*\)(/\n\t\1 (/g'

awk, এবং perl -n / p, প্রতিটি রেকর্ডে কাজ করে যা একটি লাইনে ডিফল্ট হয় তবে পরিবর্তন করা যায়; এই ক্ষেত্রে -vRS=,বা -054সাহায্য করতে পারে।
dave_thompson_085

5

আপনার যদি GNU সেড থাকে তবে আপনি ব্যবহার করতে পারেন

id username | sed 's/(/ (/4g; s/,/\n\t/g'

যা 4 র্থ এবং পরবর্তী উন্মুক্ত বন্ধনীগুলির আগে একটি স্থান যুক্ত করে, তারপরে কমাগুলি প্রতিস্থাপন করবে।


1
এটি আকর্ষণীয় দেখায়। দুর্ভাগ্যক্রমে এটি গোষ্ঠীগুলির নামগুলিকেও প্রভাবিত করে যা আমার উদাহরণ হিসাবে বন্ধনী ধারণ করে, international (uk) locationনিজের নামে নিজেই অবাঞ্ছিত স্থান .ুকিয়ে ।
রোয়াইমা

এর পরে ব্যবহার করুন s/\([[:digit:]]\+\)(/\1 (/4gযা প্যারেনেসিসের আগে অঙ্কগুলি থাকলে কেবল একটি স্থান যুক্ত করবে।
গ্লেন জ্যাকম্যান

1

@ স্টাফেন-চ্যাজেলাস যা বলেছে তা সত্য, তবে আপনি সর্বদা স্থানটি প্রথমে যুক্ত করতে এবং লাইনের পরে ভাগ করতে পারেন:

sed -e 's:\([,=][0-9]*\):\1 :g' -e 's:,:\n\t:g'

অথবা একটি সিড স্ক্রিপ্টে (ছাড়াই -e):

sed 's:\([,=][0-9]*\):\1 :g; s:,:\n\t:g'

আমরা সাধারণত /কমান্ড অনুসন্ধান (গুলি) এর বিভাজক হিসাবে ব্যবহার করি তবে এটি যে কোনও চরিত্রকেও গ্রহণ করে, তাই কখনও কখনও " :" এর মতো সংমিশ্রণ এড়ানোর জন্য " " অন্যান্য চর ব্যবহার করে পড়া সহজ হয় /\

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