ইতিমধ্যে মুছে ফেলা লাইন থেকে যেখানে ঠিকানা সীমা শুরু হয় সেখানে পজিক্স শেডের জন্য d 1 ডি; 1,2 ডি` এর জন্য কী দরকার?


11

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

ইস্যুটি মুছে ফেলা লাইনে শুরু হওয়া একটি ব্যাপ্তির আচরণ:

1d;1,2d

এই আদেশটি পৌঁছানোর আগে সীমাটির শুরু সরিয়ে নেওয়া সত্ত্বেও লাইন 2 কি মুছে ফেলা উচিত? আমার প্রাথমিক প্রত্যাশা বিএসডি সেডের সাথে সঙ্গতিপূর্ণ "না" ছিল, যখন জিএনইউ সেড "হ্যাঁ" বলেছেন, এবং স্পেসিফিকেশন পাঠ্যটি পরীক্ষা করা পুরোপুরি সমাধান করে না।

আমার প্রত্যাশাটির সাথে মিলে যাওয়া (কমপক্ষে) ম্যাকওএস এবং সোলারিস sedএবং বিএসডি sed। অসম্মতিজনক (কমপক্ষে) জিএনইউ এবং ব্যস্তবক্স sedএবং এখানে অসংখ্য লোক। প্রথম দুটি হ'ল এসইএস-প্রত্যয়িত এবং অন্যরা সম্ভবত আরও বিস্তৃত। কোন আচরণটি সঠিক?


স্পেসিফিকেশন টেক্সট দুই ঠিকানা ব্যাপ্তির জন্য বলেছেন:

Sed ইউটিলিটি তারপর, সব কমান্ড যার ঠিকানাগুলি নির্বাচন যে প্যাটার্ন স্থান ক্রমানুসারে প্রযোজ্য হইবে না হওয়া পর্যন্ত কমান্ড পরবর্তী চক্র বা দেনা-পাত্তনা মিটান শুরু হয়।

এবং

দুটি ঠিকানা সহ একটি সম্পাদনা কমান্ড প্রথম প্যাটার্ন স্পেস থেকে অন্তর্ভুক্ত ব্যাপ্তিকে নির্বাচন করবে যা দ্বিতীয় ঠিকানার সাথে মিলিত পরবর্তী প্যাটার্ন স্পেসের মাধ্যমে প্রথম ঠিকানার সাথে মিলবে। [...] নির্বাচিত ব্যাপ্তির পরে প্রথম লাইনটি শুরু করে সেড প্রথম ঠিকানাটির জন্য আবার সন্ধান করবে। এরপরে, প্রক্রিয়াটি পুনরাবৃত্তি করা হবে।

তর্কসাপেক্ষ, লাইন 2 হয় মধ্যে , কিনা শুরুর বিন্দু মুছে ফেলা হয়েছে নির্বিশেষে "প্রথম প্যাটার্ন স্থান আগামী প্যাটার্ন স্থান দ্বিতীয় সাথে মেলায় মাধ্যমে প্রথম ঠিকানার সাথে মেলায় থেকে সমেত পরিসর"। অন্যদিকে, আমি প্রত্যাশা করেছি যে প্রথমটি dপরবর্তী চক্রের দিকে এগিয়ে যাবে এবং পরিসীমাটি আরম্ভ করার সুযোগ দেবে না। ইউনিক্স-নির্ধারিত বাস্তবায়নগুলি আমার প্রত্যাশা মতো করে, তবে স্পেসিফিকেশন আদেশটি সম্ভবত তা নয়।

কিছু উদাহরণস্বরূপ পরীক্ষাগুলি অনুসরণ করে তবে মূল প্রশ্নটি হ'ল: মুছে ফেলা লাইনে যখন একটি পরিসীমা শুরু হয় তখন কী করা উচিত sed ?


পরীক্ষা এবং উদাহরণ

ইস্যুটির সরলীকৃত প্রদর্শন এটি হ'ল যা লাইনগুলি মুছার পরিবর্তে অতিরিক্ত অনুলিপিগুলি মুদ্রণ করে:

printf 'a\nb\n' | sed -e '1d;1,2p'

এটি sedইনপুট দুটি লাইন সরবরাহ করে, aএবং b। প্রোগ্রামটি দুটি কাজ করে:

  1. এর সাথে প্রথম লাইনটি মুছে ফেলে 1ddকমান্ড হবে

    প্যাটার্ন স্পেস মুছুন এবং পরবর্তী চক্রটি শুরু করুন। এবং

  2. 1 থেকে 2 পর্যন্ত রেখার ব্যাপ্তি নির্বাচন করুন এবং প্রতিটি লাইন স্বয়ংক্রিয়ভাবে প্রিন্টিংয়ের সাথে স্বতন্ত্রভাবে মুদ্রণ করে। সীমার অন্তর্ভুক্ত একটি লাইন এভাবে দু'বার প্রদর্শিত হবে।

আমার প্রত্যাশা ছিল এটি মুদ্রিত করা উচিত

b

কেবলমাত্র, সীমাটি প্রয়োগ না করায় কারণ 1,21 লাইন চলাকালীন কখনই পৌঁছায় না (কারণ dপরবর্তী চক্র / লাইনে ইতিমধ্যে ঝাঁপিয়ে aপড়েছে ) এবং তাই পরিসীমা অন্তর্ভুক্তি কখনই শুরু হয় না, যখন মুছে ফেলা হয়েছে। sedম্যাকোস এবং সোলারিস 10 এর কনফরমেন্ট ইউনিক্স এই আউটপুটটি উত্পাদন করে, যেমন sedসোলারিস এবং বিএসডি sedসাধারণভাবে নন-পসিক্স করে ।

অন্যদিকে জিএনইউ শেড প্রিন্ট করে

b
b

যা নির্দেশ করে এটা করেছে পরিসীমা বুঝিয়ে দিলেন। এটি পসিক্স মোডে এবং না উভয়ই ঘটে। বুসিবক্সের শেডের একই আচরণ রয়েছে (তবে সর্বদা অভিন্ন আচরণ নয়, তাই এটি ভাগ করা কোডের ফলাফল বলে মনে হয় না)।

সঙ্গে আরও পরীক্ষা

printf 'a\nb\nc\nd\ne\n' | sed -e '2d;2,/c/p'
printf 'a\nb\nc\nd\ne\n' | sed -e '2d;2,/d/p'

এটি নীচের লাইনে শুরু হলেও এটি মুছে ফেলা লাইনে শুরু হওয়া একটি ব্যাপ্তির সাথে আচরণ করে বলে মনে হচ্ছে । এটি দৃশ্যমান কারণ /c/পরিসীমা শেষ করতে মেলে না। /b/ব্যাপ্তি শুরু করতে ব্যবহার করা একই রকম আচরণ করে না2


প্রাথমিক কাজের উদাহরণটি আমি ব্যবহার করছিলাম

printf '%s\n' a b c d e | sed -e '1{/a/d;};1,//d'

প্রথম /a/ম্যাচ পর্যন্ত সমস্ত লাইন মুছে ফেলার উপায় হিসাবে , এটি প্রথম লাইনে থাকলেও (জিএনইউ সিড কী ব্যবহার করবে 0,/a/d- এটি এটির একটি চেষ্টা করা পসিক্স-সামঞ্জস্যপূর্ণ উপস্থাপনা ছিল)।

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

b
c
d
e

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

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

পসিক্স এখানে কি প্রয়োজন?


অস্থায়ী কর্মক্ষেত্র হিসাবে, একটি অস্থায়ী ফাইলে লিখুন এবং সম্পূর্ণরূপে edবাইপাস sedকরে পসিক্স দিয়ে এটি প্রক্রিয়া করুন ?
ডি বেন নোবল

উত্তর:


9

এটি মার্চ ২০১২-এ অস্টিন গ্রুপের মেইলিং তালিকায় উত্থাপিত হয়েছিল। এখানে চূড়ান্ত বার্তাটি দেওয়া হয়েছে (অস্টিন গ্রুপের জিওফ ক্লেয়ারের (পসিক্স বজায় রাখে এমন সংস্থা), যিনি প্রথমদিকে এই বিষয়টি উত্থাপন করেছিলেন তিনিও ছিলেন)। Gmane NNTP ইন্টারফেস থেকে এখানে অনুলিপি করা হয়েছে:

Date: Fri, 16 Mar 2012 17:09:42 +0000
From: Geoff Clare <gwc-7882/jkIBncuagvECLh61g@public.gmane.org>
To: austin-group-l-7882/jkIBncuagvECLh61g@public.gmane.org
Newsgroups: gmane.comp.standards.posix.austin.general
Subject: Re: Strange addressing issue in sed

Stephane Chazelas <stephane_chazelas-Qt13gs6zZMY@public.gmane.org> wrote, on 16 Mar 2012:
>
> 2012-03-16 15:44:35 +0000, Geoff Clare:
> > I've been alerted to an odd behaviour of sed on certified UNIX
> > systems that doesn't seem to match the requirements of the
> > standard.  It concerns an interaction between the 'n' command
> > and address matching.
> > 
> > According to the standard, this command:
> > 
> > printf 'A\nB\nC\nD\n' | sed '1,3s/A/B/;1,3n;1,3s/B/C/'
> > 
> > should produce the output:
> > 
> > B
> > C
> > C
> > D
> > 
> > GNU sed does produce this, but certified UNIX systems produce this:
> > 
> > B
> > B
> > C
> > D
> > 
> > However, if I change the 1,3s/B/C/ to 2,3s/B/C/ then they produce
> > the expected output (tested on Solaris and HP-UX).
> > 
> > Is this just an obscure bug from common ancestor code, or is there
> > some legitimate reason why this address change alters the behaviour?
> [...]
> 
> I suppose the idea is that for the second 1,3cmd, line "1" has
> not been seen, so the 1,3 range is not entered.

Ah yes, now it makes sense, and it looks like the standard does
require this slightly strange behaviour, given how the processing
of the "two addresses" case is specified:

    An editing command with two addresses shall select the inclusive
    range from the first pattern space that matches the first address
    through the next pattern space that matches the second.  (If the
    second address is a number less than or equal to the line number
    first selected, only one line shall be selected.) Starting at the
    first line following the selected range, sed shall look again for
    the first address. Thereafter, the process shall be repeated.

It's specified this way because the addresses can be BREs, but if
the same matching process is applied to the line numbers (even though
they can only match at most once), then the 1,3 range on that last
command is never entered.

-- 
Geoff Clare <g.clare-7882/jkIBncuagvECLh61g@public.gmane.org>
The Open Group, Apex Plaza, Forbury Road, Reading, RG1 1AX, England

এবং জিওফ যে বার্তাগুলির উদ্ধৃতি দিয়েছিলেন তার বাকী অংশটির প্রাসঙ্গিক অংশটি এখানে:

I suppose the idea is that for the second 1,3cmd, line "1" has
not been seen, so the 1,3 range is not entered.

Same idea as in

printf '%s\n' A B C | sed -n '1d;1,2p'

whose behavior differ in traditional (heirloom toolchest at
least) and GNU.

It's unclear to me whether POSIX wants one behavior or the
other.

সুতরাং, (জেফের মতে) পসিএক্স স্পষ্ট যে জিএনইউ আচরণটি অনুপযুক্ত।

আর এটা সত্যি এটি কম সামঞ্জস্যপূর্ণ এর (তুলনা seq 10 | sed -n '1d;1,2p'সঙ্গে seq 10 | sed -n '1d;/^1$/,2p') এমনকি সম্ভাব্য কম বিস্ময়কর যদি মানুষ যারা বুঝতে পারছি না কিভাবে রেঞ্জ প্রসেস করা হয় (এমনকি জিওফ প্রাথমিকভাবে অনুসারী আচরণ পাওয়া "অদ্ভুত" )।

কেউ এটিকে জিএনইউ লোকদের কাছে বাগ হিসাবে রিপোর্ট করা বিরক্ত করেনি। আমি নিশ্চিত নই যে আমি এটিকে বাগ হিসাবে যোগ্য করে তুলেছি। উভয় আচরণকে এটি পরিষ্কার করে দেওয়া যে কেউ একটির উপর নির্ভর করতে পারে না তা নিশ্চিত করার জন্য সম্ভবত পসিক্স স্পেসিফিকেশন আপডেট করার পক্ষে সর্বোত্তম বিকল্প হবে।

সম্পাদনা করুনsed70 এর দশকের শেষের দিক থেকে আমি এখন ইউনিক্স ভি 7- তে আসল বাস্তবায়নটি দেখেছি এবং এটি দেখতে দেখতে অনেকটা এমন মনে হচ্ছে যে সংখ্যাসূচক ঠিকানাগুলির আচরণের উদ্দেশ্য ছিল না বা কমপক্ষে সেখানে সম্পূর্ণরূপে চিন্তা করা হয়নি।

জিওফের স্পেকটি পড়ার সাথে (এবং এটি কেন ঘটে তার আমার মূল ব্যাখ্যা), বিপরীতে, এতে:

seq 5 | sed -n '3d;1,3p'

1, 2, 4 এবং 5 লাইনগুলি আউটপুট হওয়া উচিত, কারণ এইবার এটি শেষ ঠিকানা যা কখনই 1,3pরেঞ্জযুক্ত কমান্ডের মুখোমুখি হয় না , যেমনseq 5 | sed -n '3d;/1/,/3/p'

তবুও, এটি আসল বাস্তবায়নে ঘটে না, বা অন্য যে কোনও বাস্তবায়ন আমি চেষ্টা করেছি (ব্যস্তবক্সটি sed1, 2 এবং 4 লাইনে ফিরে আসে যা বাগের মতো দেখায়)।

আপনি যদি ইউএনআইএক্স ভি code কোডটি দেখেন তবে এটি বর্তমান সংখ্যার শেষের ঠিকানাটির চেয়ে বর্তমান লাইন সংখ্যাটি আরও বেশি, এবং এর পরে সীমা ছাড়িয়ে যাবে for এটি সূচনার ঠিকানার জন্য এটি না করে এমন ঘটনা ইচ্ছাকৃত ডিজাইনের চেয়ে তদারকির মতো দেখায়।

এর অর্থ হ'ল এমন কোনও বাস্তবায়ন নেই যা এই মুহূর্তে POSIX স্পেকের সেই ব্যাখ্যার সাথে সামঞ্জস্যপূর্ণ।

জিএনইউ বাস্তবায়নের সাথে আরেকটি বিভ্রান্তিকর আচরণ হ'ল:

$ seq 5 | sed -n '2d;2,/3/p'
3
4
5

যেহেতু 2 লাইনটি এড়িয়ে গেছে, 2,/3/3 টি লাইনটিতে প্রবেশ করা হয়েছে (প্রথম লাইন যার সংখ্যা> = 2)। তবে এটি যে রেখাটি আমাদের সীমাতে প্রবেশ করিয়েছে, এটি শেষ ঠিকানার জন্য পরীক্ষা করা হয়নি । এটি এর সাথে আরও খারাপ busybox sedহয়:

$ seq 10 | busybox sed -n '2,7d; 2,3p'
8

যেহেতু 2 থেকে 7 লাইনগুলি মুছে ফেলা হয়েছে, তাই লাইন 8 হ'ল প্রথমটি যা = = 2 তাই তখন 2,3 পরিসর প্রবেশ করা হয় !


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

1
@ মিশেলহোমর, ধারণাটি হ'ল (জেফের মতে) পসিএক্স স্পষ্ট যে জিএনইউ আচরণটি অনুপযুক্ত। আর এটা সত্যি এটি কম সামঞ্জস্যপূর্ণ এর (তুলনা seq 10 | sed -n '1d;1,2p'সঙ্গে seq 10 | sed -n '1d;/^1$/,2p') এমনকি যদি সম্ভাব্য কম মানুষ বিস্ময়কর বুঝতে পারছি না হবে কিভাবে রেঞ্জ প্রক্রিয়া করা হয়। কেউ এটিকে জিএনইউ লোকদের কাছে বাগ হিসাবে রিপোর্ট করা বিরক্ত করেনি। আমি নিশ্চিত নই যে আমি এটিকে বাগ হিসাবে যোগ্য করে তুলেছি, সম্ভবত সর্বোত্তম বিকল্প হ'ল উভয় আচরণকে এটি পরিষ্কার করে দেওয়া যে কেউ একটির উপরও নির্ভর করতে পারে না তা নিশ্চিত করার জন্য পসিক্স স্পেক আপডেট করা।
স্টাফেন চেজেলাস

2
প্রকৃতপক্ষে, পসিক্স সংজ্ঞাটি কোনও ঠিকানা সীমা শুরু করতে বা শেষ করতে ঠিকানাগুলি "দেখা" হওয়া দরকার বলে কোনও বিবৃতি দেয় না, জিএনইউ বাস্তবায়ন পজিক্স শব্দটিকে আরও কঠোরভাবে অনুসরণ করে (জিএনইউর জন্য আশ্চর্যজনক!)। আমি জানি বেশিরভাগ বাস্তব-বিশ্বের ক্ষেত্রে এটিও কাঙ্ক্ষিত আচরণ। তবে, আপনি উল্লেখ হিসাবে, এটি সামঞ্জস্য করা প্রয়োজন। এবং বিস্তৃত নিদর্শনগুলির জন্য প্রতিটি লাইন চেক করেওd কেবলমাত্র পারফরম্যান্সের সমস্যা নয়, এটি আরও বাস্তবায়নের সমস্যার দিকে নিয়ে যায় কারণ পরিসীমাগুলির জন্য প্রয়োজনীয় "অদেখা" নিদর্শনগুলি আরও খালি নিদর্শনগুলিতে প্রভাবিত হওয়ার অনুমতি দেয় না ... গোলযোগ!
ফিলিপস

@ ফিলিপোস, সেই 1d;1,2pস্ক্রিপ্টে 1,2pকমান্ডটি প্রথম লাইনে চালিত হয় না, সুতরাং কোনও ঠিকানার জায়গার সাথে প্রথম ঠিকানাটি মিলছে না , যা এই পাঠ্যের ব্যাখ্যা করার এক উপায়। যে কোনও ক্ষেত্রে, এটি স্পষ্ট হওয়া উচিত যে কমান্ডটি চালিত হওয়ার সময় ঠিকানাগুলির মূল্যায়ন করা উচিত। লাইক ইনsed 's/./x/g; /xxx/,/xxx/d'
স্টাফেন চেজেলাস

2
@ ইসহাক, এটিই মূল বিষয়। পসিক্স ভাষায় 1এবং /1/উভয় ঠিকানা, 1লাইন নম্বর 1 /1/হলে ঠিকানাটি কী প্যাটার্ন স্পেস থাকে যখন ঠিকানা 1, প্রশ্নটি হয় যে উভয় প্রকারের ঠিকানা একইরকম হওয়া উচিত, অথবা লাইন সংখ্যা রেঞ্জ বিবেচনা করা উচিত কিনা " নিখুঁত "তারা মিলছে কিনা তা নির্বিশেষে। আরও historicalতিহাসিক প্রসঙ্গে আমার সর্বশেষ সম্পাদনাটিও দেখুন।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.