অ লোভী (অনিচ্ছা) রেডেক্সের সাথে মিলছে?


406

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

সুতরাং থেকে:

http://www.suepearson.co.uk/product/174/71/3816/

আমি চাই:

http://www.suepearson.co.uk/

(হয় পিছনে স্ল্যাশ সহ বা ছাড়া, এটি কোনও ব্যাপার নয়)

আমি চেষ্টা করেছি:

 sed 's|\(http:\/\/.*?\/\).*|\1|'

এবং (অ-লোভী কোয়ান্টিফায়ারকে রক্ষা করা)

sed 's|\(http:\/\/.*\?\/\).*|\1|'

তবে আমি অ-লোভী কোয়ান্টিফায়ার ( ?) -কে কাজ করতে পাই না বলে মনে হয় না , তাই এটি সর্বদা পুরো স্ট্রিংয়ের সাথে মিলে যায়।


54
একটি পার্শ্ব-নোট: আপনি যদি "|" দিয়ে আপনার রেজিڪسগুলি সীমাবদ্ধ করেন, আপনার "/" গুলি এড়াতে হবে না। প্রকৃতপক্ষে, বেশিরভাগ লোক "|" দিয়ে সীমিত করে দেয় "পিকেট বেড়া" এড়ানোর জন্য "/" এর পরিবর্তে।
AttishOculus

12
@ আতিশকুলাস সেডের বিকল্প বিকল্পে 's' এর পরে প্রথম চরিত্রটি হ'ল ডিলিমিটার। সুতরাং 's ^ foo ^ বার ^' বা 'গুলি! ফু! বার!' এছাড়াও কাজ করুন
স্কুইডলি

1
প্রসারিত রেজেক্সের জন্য, ব্যবহার করুন sed -E 's...। তবুও, কোনও অনিচ্ছুক অপারেটর নেই।
ওন্দ্রা Žižka

প্রশ্নের শিরোনামের উত্তর নয় তবে এই নির্দিষ্ট ক্ষেত্রে সহজ cut -d'/' -f1-3কাজ করে।
পেট্রা জাভেরিক

উত্তর:


421

মৌলিক বা বর্ধিত পোস্টিক্স / জিএনইউ রেজেক্স অ-লোভী কোয়ান্টিফায়ারকে স্বীকৃতি দেয় না; আপনার একটি পরবর্তী রেজেক্স দরকার। ভাগ্যক্রমে, এই প্রসঙ্গে পার্ল রেজেক্সটি পাওয়া খুব সহজ:

perl -pe 's|(http://.*?/).*|\1|'

12
এটি জায়গায় ব্যবহারের বিকল্পগুলির জন্য -pi -e
সত্যই সুন্দর

11
পবিত্র Smokes আমি বিশ্বাস করতে পারছি না যে কাজ :-) শুধু sucks আমার স্ক্রিপ্ট একটি পার্ল নির্ভরতা :-( হয়েছে প্লাস পাশ দিয়ে এখন, প্রায় প্রতিটি লিনাক্স ডিস্ট্রো পার্ল ইতিমধ্যে সম্ভবত না একটি বিষয় :-) হয়েছে
Freedom_Ben

6
@Freedom_Ben: IIRC perlহয় প্রয়োজনীয় POSIX দ্বারা
MestreLion

4
@ ডলফাস ৩৩৩: "বেসিক বা এক্সটেন্ডেড পিক্সিক্স / জিএনইউ রেজেক্স উভয়ই লোভী কোয়ান্টিফায়ারকে চিনতে পারে না" এর অর্থ "আপনি সেজে নন-লোভী কোয়ান্টিফায়ার ব্যবহার করতে পারবেন না"।
বিশৃঙ্খলা

3
@ সের্গিও কিভাবে এটি আপনার জিনিস অনুরোধ, যা অসম্ভব হয় করি sed, একটি বাক্য গঠন মূলত যে অভিন্ন ব্যবহারsed
বিশৃঙ্খলার

250

এই নির্দিষ্ট ক্ষেত্রে, আপনি অ-লোভী রেজেক্স ব্যবহার না করে কাজটি সম্পন্ন করতে পারেন।

[^/]*পরিবর্তে এই লোভী রেজেক্স ব্যবহার করে দেখুন .*?:

sed 's|\(http://[^/]*/\).*|\1|g'

3
এই কৌশলটি ব্যবহার করে কীভাবে সেড ম্যাচ অ লোভী একটি বাক্যাংশ তৈরি করবেন?
ব্যবহারকারী3694243

6
দুর্ভাগ্যক্রমে আপনি পারবেন না; দেখতে বিশৃঙ্খলার এর উত্তর
ড্যানিয়েল এইচ

অনেক ধন্যবাদ ... যেহেতু পার্ল অনেকগুলি লিনাক্স ডিস্ট্রোজে ডিফল্ট ইনস্টলেশন বেসে আর নেই!
st0ne


@ দানিএলএইচ অনুরোধ অনুসারে এই কৌশলটি অ-লোভজনকভাবে ব্যবহার করে বাক্যাংশগুলি মিলানো সম্ভব । পর্যাপ্ত নির্ভুলতার সাথে প্যাটার্নটি লিখতে কেবল কিছুটা ব্যথা লাগতে পারে। উদাহরণস্বরূপ, কোনও ইউআরএল-এর ক্যোয়ারিতে কোনও মূল-মান-অ্যাসাইনমেন্টটি বিশ্লেষণ করার সময় এটি ব্যবহার করে অ্যাসাইনমেন্ট অনুসন্ধান করতে হতে পারে ([^&=#]+)=([^&#]*)। এমন কেসগুলি রয়েছে যা নিশ্চিতভাবে এইভাবে কাজ করে না, উদাহরণস্বরূপ, তার হোস্ট অংশের জন্য ইউআরএল এবং পার্সোনাল যখন চূড়ান্ত স্ল্যাশ সহ পথের নাম ক্যাপচারিং থেকে বাদ দেওয়া হবে:^(http:\/\/.+?)/?$
থমাস আরবান

121

সেড সহ, আমি সাধারণত বিভাজক পর্যন্ত বিভাজক ব্যতীত অন্য কোনও কিছু অনুসন্ধান করে অ-লোভী অনুসন্ধান প্রয়োগ করি:

echo "http://www.suon.co.uk/product/1/7/3/" | sed -n 's;\(http://[^/]*\)/.*;\1;p'

আউটপুট:

http://www.suon.co.uk

এই:

  • আউটপুট না -n
  • অনুসন্ধান, মিলের প্যাটার্ন, প্রতিস্থাপন এবং মুদ্রণ করুন s/<pattern>/<replace>/p
  • ব্যবহার ;অনুসন্ধান কমান্ড বিভাজক পরিবর্তে /এটা এত টাইপ করতে সহজ করতেs;<pattern>;<replace>;p
  • বন্ধনীগুলির মধ্যে ম্যাচটি মনে রাখবেন \(... \), এর সাথে পরে অ্যাক্সেসযোগ্য \1, \2...
  • ম্যাচ http://
  • বন্ধনীতে কিছু অনুসরণ করার পরে [], [ab/]অর্থ হয় aবা হয় বা bor/
  • প্রথম ^মধ্যে []উপায়ে not, তাই কিছু দ্বারা অনুসরণ কিন্তু জিনিস[]
  • সুতরাং চরিত্র [^/]ব্যতীত অন্য কোনও কিছুর অর্থ/
  • *পূর্ববর্তী গ্রুপটির পুনরাবৃত্তি করা [^/]*মানে অক্ষর বাদে /
  • এখন অবধি sed -n 's;\(http://[^/]*\)অনুসন্ধান এবং মনে রাখার http://পরে কোনও অক্ষর অনুসরণ করা /এবং আপনি কী খুঁজে পেয়েছেন তা মনে রাখবেন
  • আমরা ডোমেনের শেষ প্রান্তটি অনুসন্ধান করতে চাইছি তাই পরের দিকে থামি /তাই /শেষে অন্যটি যুক্ত করুন : sed -n 's;\(http://[^/]*\)/'তবে আমরা ডোমেনের পরে বাকী লাইনের সাথে মিল রাখতে চাই তাই যুক্ত করুন.*
  • এখন গ্রুপ 1 ( \1) এ মনে রাখা ম্যাচটি হ'ল ডোমেন তাই গ্রুপ \1এবং মুদ্রণে সংরক্ষিত স্টাফের সাথে মিলিত লাইনটি প্রতিস্থাপন করুন :sed -n 's;\(http://[^/]*\)/.*;\1;p'

আপনি যদি ডোমেনের পরেও ব্যাকস্ল্যাশ অন্তর্ভুক্ত করতে চান তবে মনে রাখার জন্য গ্রুপে আরও একটি ব্যাকস্ল্যাশ যুক্ত করুন:

echo "http://www.suon.co.uk/product/1/7/3/" | sed -n 's;\(http://[^/]*/\).*;\1;p'

আউটপুট:

http://www.suon.co.uk/

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

2
একটি স্ট্রিং দ্বারা বিভাজক প্রতিস্থাপন করা সম্ভব?
ক্যালকুলেমাস

37

সেড "লোভী নন" অপারেটরকে সমর্থন করে না।

ম্যাচ থেকে "/" বাদ দিতে আপনাকে "[]" অপারেটরটি ব্যবহার করতে হবে।

sed 's,\(http://[^/]*\)/.*,\1,'

PS "/" ব্যাকস্ল্যাশ করার দরকার নেই।


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

1
প্রশ্নটি আরও সাধারণ ছিল। এই সমাধানগুলি ইউআরএলগুলির জন্য কাজ করে তবে (উদাহরণস্বরূপ) আমার পিছনে পিছনের শূন্যগুলি ব্যবহারের ক্ষেত্রে ব্যবহার করে না। s/([[:digit:]]\.[[1-9]]*)0*/\1/স্পষ্টতই ভাল কাজ করবে না 1.20300। যেহেতু মূল প্রশ্নটি ইউআরএল সম্পর্কে ছিল, তবে তাদের গ্রহণযোগ্য উত্তরে উল্লেখ করা উচিত।
ড্যানিয়েল এইচ

33

অলস অনুকরণ (অ-লোভী) কোয়ান্টিফায়ার ইন ulating sed

এবং অন্যান্য সমস্ত রেগেক্স স্বাদ!

  1. একটি অভিব্যক্তি প্রথম ঘটনা সন্ধান করা:

    • পজিক্স আগে ( -rবিকল্প ব্যবহার করে )

      Regex:

      (EXPRESSION).*|.

      SED:

      sed -r 's/(EXPRESSION).*|./\1/g' # Global `g` modifier should be on

      উদাহরণ (অঙ্কগুলির প্রথম ক্রম সন্ধান করা) লাইভ ডেমো :

      $ sed -r 's/([0-9]+).*|./\1/g' <<< 'foo 12 bar 34'
      12

      এটা কিভাবে কাজ করে ?

      এই রেজেক্স একটি বিকল্প থেকে উপকার করে |। প্রতিটি অবস্থানে ইঞ্জিন দীর্ঘতম ম্যাচটি বাছাই করার চেষ্টা করে (এটি একটি পসিক্স স্ট্যান্ডার্ড যা বেশ কয়েকটি অন্যান্য ইঞ্জিন অনুসরণ করে) যার অর্থ এটি .কোনও ম্যাচ না পাওয়া পর্যন্ত চলে ([0-9]+).*। তবে অর্ডারও গুরুত্বপূর্ণ।

      এখানে চিত্র বর্ণনা লিখুন

      যেহেতু বৈশ্বিক পতাকা সেট করা আছে, ইঞ্জিনটি ইনপুট স্ট্রিং বা আমাদের টার্গেটের শেষে অক্ষর অনুসারে অক্ষরটির সাথে মিলিয়ে যাওয়ার চেষ্টা করে। অল্টারনেশনের প্রথম এবং একমাত্র ক্যাপচারিং গোষ্ঠীর সাথে মিলে যাওয়া (EXPRESSION)বাকী লাইনের সাথে সাথে তত্ক্ষণাত গ্রাস করা হয় .*। আমরা এখন প্রথম ক্যাপচারিং গ্রুপে আমাদের মানটি ধরে রেখেছি।

    • পজিক্স BRE

      Regex:

      \(\(\(EXPRESSION\).*\)*.\)*

      SED:

      sed 's/\(\(\(EXPRESSION\).*\)*.\)*/\3/'

      উদাহরণ (অঙ্কগুলির প্রথম ক্রম সন্ধান করা):

      $ sed 's/\(\(\([0-9]\{1,\}\).*\)*.\)*/\3/' <<< 'foo 12 bar 34'
      12

      এটি একটি পূর্ব সংস্করণের মতো তবে কোনও বিকল্প জড়িত নেই। এখানেই শেষ. প্রতিটি একক অবস্থানে ইঞ্জিন একটি সংখ্যার সাথে মেলে চেষ্টা করে।

      এখানে চিত্র বর্ণনা লিখুন

      যদি পাওয়া যায়, অন্যান্য নিম্নলিখিত সংখ্যা খাওয়া এবং বন্দী এবং লাইন বাকি থেকে অবিলম্বে অন্যথায় মিলেছে করা হয় *মানে বেশী বা শূন্য এটি উপর দ্বিতীয় ক্যাপচারিং গ্রুপ অগ্রাহ্য \(\([0-9]\{1,\}\).*\)*একটি বিন্দু আসে .একটি অক্ষর মেলে এবং এই প্রক্রিয়া চলতে থাকে।

  2. একটি বিস্মৃত প্রকাশের প্রথম ঘটনাটি সন্ধান করা :

    এই পদ্ধতির সীমানা ছাড়ানো স্ট্রিংয়ের প্রথম উপস্থিতির সাথে মিলবে। আমরা এটিকে স্ট্রিংয়ের একটি ব্লক বলতে পারি।

    sed 's/\(END-DELIMITER-EXPRESSION\).*/\1/; \
         s/\(\(START-DELIMITER-EXPRESSION.*\)*.\)*/\1/g'

    ইনপুট স্ট্রিং:

    foobar start block #1 end barfoo start block #2 end

    -EDE: end

    -SDE: start

    $ sed 's/\(end\).*/\1/; s/\(\(start.*\)*.\)*/\1/g'

    আউটপুট:

    start block #1 end

    প্রথম রেজেক্স প্রথম প্রান্তযুক্ত \(end\).*ডিলিমিটারের endসাথে মেলে এবং ক্যাপচার করে এবং সাম্প্রতিক গৃহীত অক্ষরগুলির সাথে সমস্ত ম্যাচকে প্রতিস্থাপন করে যা শেষ ডিলিমিটার। এই পর্যায়ে আমাদের আউটপুট হল: foobar start block #1 end

    এখানে চিত্র বর্ণনা লিখুন

    তারপরে ফলাফলটি দ্বিতীয় রেজেক্সে পাস করা হয়েছে \(\(start.*\)*.\)*যা উপরের পসিক্স বিআরই সংস্করণের মতো। এটি একটি একক অক্ষরের startসাথে মিলে যায় যদি শুরু ডিলিমিটারটি না মেলে অন্যথায় এটি শুরু ডিলিমিটারের সাথে মেলে এবং ক্যাপচার করে এবং বাকী অক্ষরের সাথে মেলে।

    এখানে চিত্র বর্ণনা লিখুন


সরাসরি আপনার প্রশ্নের উত্তর

# 2 পদ্ধতির (সীমিত প্রকাশ) ব্যবহার করে আপনার দুটি উপযুক্ত অভিব্যক্তি নির্বাচন করা উচিত:

  • Ede: [^:/]\/

  • SDE: http:

ব্যবহার:

$ sed 's/\([^:/]\/\).*/\1/g; s/\(\(http:.*\)*.\)*/\1/' <<< 'http://www.suepearson.co.uk/product/174/71/3816/'

আউটপুট:

http://www.suepearson.co.uk/

দ্রষ্টব্য: এটি অভিন্ন প্রেরকগুলির সাথে কাজ করবে না।


3) ডেমোর জন্য regex101 এর মতো সাইটের পরামর্শ দেওয়ার সময়, দয়া করে একটি নোট যুক্ত করুন যে সিনট্যাক্স এবং বৈশিষ্ট্যগত পার্থক্যের কারণে ক্লাইট সরঞ্জামগুলির জন্য এটি সর্বদা উপযুক্ত নয়
সন্দীপ

1
@ সন্দীপ ধন্যবাদ আমি এই সমস্ত উক্তিটি একক উদ্ধৃতিতে পরিণত করেছি। এছাড়াও আমি উল্লেখ করা বামতম দীর্ঘতম ম্যাচের নিয়ম বিবেচনা করেছি। যাইহোক sedএবং অন্যান্য সমস্ত ইঞ্জিন একই মানের ক্রম অনুসরণ করে যখন এটি সাম্যের দিকে আসে তখন বিষয়টি বিবেচনা করে । সুতরাং echo 'foo 1' | sed -r 's/.|([0-9]+).*/\1/g'একটি ম্যাচ না কিন্তু echo 'foo 1' | sed -r 's/([0-9]+).*|./\1/g'আছে।
রেভো

@ সুনদীপও সীমান্ত প্রকাশের জন্য কাজ করতে পারেননি একইরকম শুরু এবং শেষের সীমান্তকারীর জন্য যা আমি এর জন্য একটি নোট যুক্ত করেছি।
রেভো

যখন বিভিন্ন বিকল্প একই স্থান থেকে শুরু হয় এবং একই দৈর্ঘ্য হয় তখন কী ঘটে যায় সে সম্পর্কে দুর্দান্ত পয়েন্ট, অনুমান করুন যে অন্যান্য ইঞ্জিনগুলির মতো বাম-ডান ক্রমটি অনুসরণ করবে .. এটি ম্যানুয়ালটিতে বর্ণিত হয়েছে কিনা সন্ধান করতে হবে
সন্দীপ

যদিও এখানে একটি অদ্ভুত ঘটনা রয়েছে: স্ট্যাকওভারফ্লো
সন্দীপ

20

একক চরিত্রের চেয়ে বেশি লোভী সমাধান

এই থ্রেডটি সত্যই পুরানো তবে আমি ধরে নিই যে লোকেরা এখনও এটির প্রয়োজন। বলুন আপনি প্রথম ঘটনাটি না হওয়া পর্যন্ত সমস্ত কিছু হত্যা করতে চান HELLO। আপনি বলতে পারবেন না [^HELLO]...

সুতরাং একটি দুর্দান্ত সমাধান দুটি ধাপের সাথে জড়িত, ধরে নিই যে আপনি কোনও অনন্য শব্দটি ছাড়তে পারবেন যা আপনি ইনপুটটিতে প্রত্যাশা করছেন না, বলুন top_sekrit

এই ক্ষেত্রে আমরা করতে পারি:

s/HELLO/top_sekrit/     #will only replace the very first occurrence
s/.*top_sekrit//        #kill everything till end of the first HELLO

অবশ্যই, একটি সহজ ইনপুট দিয়ে আপনি একটি ছোট শব্দ ব্যবহার করতে পারেন, বা এমনকি একটি একক অক্ষরও।

আছে HTH!


4
এটিকে আরও উন্নততর করার জন্য, যখন আপনি অব্যবহৃত চরিত্রের প্রত্যাশা করতে পারবেন না তেমন দরকারী: 1. বিশেষ চরিত্রটি সত্যই অব্যবহৃত ওয়ার্ডের সাথে প্রতিস্থাপন করুন, ২. বিশেষ চরিত্রের সাথে শেষের অনুক্রমটি প্রতিস্থাপন করুন, ৩. বিশেষ অক্ষরের সাথে অনুসন্ধান শেষ করুন, ৪ ... বিশেষ অক্ষর ফিরে, 5 প্রতিস্থাপন বিশেষ Word পিছনে। উদাহরণস্বরূপ, আপনি <hello> এবং </hello> এর মধ্যে একটি লোভী অপারেটর চান:
জাকুব

3
উদাহরণস্বরূপ: প্রতিধ্বনি "অনুসন্ধান করুন: <হেলো> ফার্স্ট <br> হ্যা </ হেলো> <হেলো> সেকেন্ড ~ অন্ড </ হেলো>" | সেড-এ ",, ~, ভেরিপিসিয়াল, জি" -ই "এস, </ শেলো>, g, জি" -ই "এস, * খুঁজে নিন: <শেলো> ([^ ~] *)। *, \ 1 , "-e" এস, \ ~, </hello>, "-e" গুলি, প্রচুর, ~, "
জাকুব ২:0

2
আমি রাজী. সুন্দর সমাধান আমি এই মন্তব্যে পুনরায় মন্তব্য করব: আপনি যদি un অব্যক্ত থাকার উপর নির্ভর করতে না পারেন তবে এর বর্তমান ঘটনাগুলি প্রথমে s / ~ / VERYspeciaL / g ব্যবহার করে প্রতিস্থাপন করুন, তারপরে উপরের কৌশলটি ব্যবহার করুন, তারপরে s / VERYspeciaL / ~ / g ব্যবহার করে আসলটি ফিরিয়ে দিন
ইশাহাক

1
আমি এই জাতীয় জিনিসের জন্য বিরল "ভেরিয়েবল" ব্যবহার করতে পছন্দ করি, তাই পরিবর্তে `আমি ব্যবহার করতাম <$$>(যেহেতু $$শেলটিতে আপনার প্রসেস আইডি প্রসারিত হয়, যদিও আপনাকে একক উদ্ধৃতিগুলির চেয়ে দ্বিগুণ উদ্ধৃতি ব্যবহার করতে হবে, এবং এটি আপনার রেজেক্সের অন্যান্য অংশগুলি ভেঙে ফেলতে পারে) বা, যদি ইউনিকোড পাওয়া যায় তবে এর মতো কিছু <∈∋>
অ্যাডাম কাটজ

এক পর্যায়ে আপনি নিজেকে জিজ্ঞাসা করতে কেন আপনি শুধু ব্যবহার করছেন না আছে perlবা pythonপরিবর্তে অথবা অন্য কোনো ভাষা। perlএটি একটি একক লাইনে কম ভঙ্গুর পদ্ধতিতে করে ...
আর্টঅফ ওয়ারফেয়ার

18

সেড - ক্রিস্টোফ সিগার্টের অ-লোভী মিল

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

লোভী মিলছে

% echo "<b>foo</b>bar" | sed 's/<.*>//g'
bar

লোভী মিল নেই

% echo "<b>foo</b>bar" | sed 's/<[^>]*>//g'
foobar

17

এটি কাটা ব্যবহার করে করা যেতে পারে:

echo "http://www.suepearson.co.uk/product/174/71/3816/" | cut -d'/' -f1-3

9

আরেকটি উপায়, রিজেক্স ব্যবহার না করা, ক্ষেত্র / ডিলিমিটার পদ্ধতি যেমন ব্যবহার করা

string="http://www.suepearson.co.uk/product/174/71/3816/"
echo $string | awk -F"/" '{print $1,$2,$3}' OFS="/"

5

sed অবশ্যই এর জায়গা আছে কিন্তু এটি তাদের মধ্যে একটিও নয়!

ডি যেমন নির্দেশ করেছেন: কেবল ব্যবহার করুন cut। এটি অনেক সহজ এবং এই ক্ষেত্রে অনেক বেশি নিরাপদ। এখানে উদাহরণ রয়েছে যেখানে আমরা ইউএসএল থেকে বাশ সিনট্যাক্স ব্যবহার করে বিভিন্ন উপাদান বের করেছি:

url="http://www.suepearson.co.uk/product/174/71/3816/"

protocol=$(echo "$url" | cut -d':' -f1)
host=$(echo "$url" | cut -d'/' -f3)
urlhost=$(echo "$url" | cut -d'/' -f1-3)
urlpath=$(echo "$url" | cut -d'/' -f4-)

আপনি দেয়:

protocol = "http"
host = "www.suepearson.co.uk"
urlhost = "http://www.suepearson.co.uk"
urlpath = "product/174/71/3816/"

আপনি দেখতে পাচ্ছেন এটি অনেক বেশি নমনীয় পদ্ধতি।

(সমস্ত কৃতিত্ব ডি কে)


3
sed 's|(http:\/\/[^\/]+\/).*|\1|'

1
আপনি যদি "|" ব্যবহার করেন আপনার বিভাজক হিসাবে, "/" পালানোর দরকার নেই।
মাইকেল

3

সেড-ই নিয়মিত এক্সপ্রেশনগুলি বর্ধিত (আধুনিক) নিয়মিত এক্সপ্রেশন হিসাবে ব্যাখ্যা করে

আপডেট: - ম্যাকোস এক্স-এ, জিএনইউ সেডে -আর।


4
না এটি হয় না ... কমপক্ষে জিএনইউ সিড নয়।
মিশেল ডি রুইটার

7
আরও বিস্তৃতভাবে, -EBSD এর জন্য অনন্য sedএবং অতএব ওএস এক্স man ম্যান পৃষ্ঠাগুলির লিঙ্ক। -rবাড়ানো রেগুলার এক্সপ্রেশনের আনতে পারে গনুহsed যেমন @ stephancheg এর সংশোধন লক্ষনীয়। 'নিক বিতরণ জুড়ে পরিচিত পরিবর্তনশীলতার একটি কমান্ড ব্যবহার করার সময় সতর্ক থাকুন। আমি যে হার্ড উপায় শিখেছি।
চমত্কার

1
আপনি যদি সেড ব্যবহার করতে চান তবে এটি সঠিক উত্তর এবং প্রাথমিক প্রশ্নের ক্ষেত্রে এটি সর্বাধিক প্রযোজ্য।
উইল টাইপ

8
তথ্য ফাইল এবং কিছু দ্রুত পরীক্ষা -rঅনুযায়ী জিএনইউ সেডের বিকল্পটি কেবল পালানোর নিয়মগুলিকে পরিবর্তন করে Appendix A Extended regular expressions; এটি আসলে একটি অ-লোভী GNU sed version 4.2.1
বাছাইকারীকে

1
GNU সেড কিছু-E সময়ের জন্য একটি অননুমোদিত বিকল্প হিসাবে স্বীকৃত , তবে 4.2.2.177 প্রকাশে ডকুমেন্টেশনটি প্রতিফলিত করার জন্য আপডেট করা হয়েছে, -Eএখন উভয়ের পক্ষে ঠিক আছে।
বেনিয়ামিন ডাব্লু।

3

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

sed -r -e ":loop" -e 's|(http://.+)/.*|\1|' -e "t loop"
  • -r: প্রসারিত রেজেক্স ব্যবহার করুন (+ এবং অনস্কেপড প্রথম বন্ধনীগুলির জন্য)
  • ": লুপ": "লুপ" নামে একটি নতুন লেবেল সংজ্ঞায়িত করুন
  • -e: সিডে কমান্ড যুক্ত করুন
  • "টি লুপ": সফল প্রতিস্থাপন থাকলে "লুপ" লেবেলে ফিরে যান

এখানে কেবল সমস্যাটি হ'ল এটি শেষ বিভাজক চরিত্রটিও ('/') কেটে ফেলবে, তবে আপনার যদি সত্যিই এটির প্রয়োজন হয় তবে "লুপ" শেষ হওয়ার পরে আপনি কেবল এটি পিছনে রাখতে পারেন, কেবল পূর্বের শেষে এই অতিরিক্ত কমান্ডটি যুক্ত করুন কমান্ড লাইন:

-e "s,$,/,"

2

কারণ আপনি নির্দিষ্ট করে বলেছেন যে আপনি সেড (পার্ল, কাট ইত্যাদির পরিবর্তে) ব্যবহার করার চেষ্টা করছেন, গ্রুপিংয়ের চেষ্টা করুন। এটি অ-লোভী শনাক্তকারীকে সম্ভাব্যরূপে স্বীকৃতি না দেওয়া থেকে বিরত রাখে। প্রথম গোষ্ঠী হ'ল প্রোটোকল (যেমন 'http: //', 'https: //', 'tcp: //', ইত্যাদি)। দ্বিতীয় গ্রুপটি হল ডোমেন:

প্রতিধ্বনি "http://www.suon.co.uk/product/1/7/3/" | সেড "এস | ^ \ (। * // \) \ ([^ /] * \)। * $ | \ 1 \ 2 |"

আপনি যদি গ্রুপিংয়ের সাথে পরিচিত না হন তবে এখানেই শুরু করুন


1

আমি বুঝতে পারি এটি একটি পুরানো প্রবেশ, তবে কেউ এটি দরকারী হতে পারে। সম্পূর্ণ ডোমেন নাম হিসাবে 253 অক্ষর প্রতিস্থাপনের মোট দৈর্ঘ্য অতিক্রম করতে পারে না। * সঙ্গে। {{1, 255 \}


1

এইভাবে সেড ব্যবহার করে মাল্টি-ক্যারেক্টার স্ট্রিংগুলির অ-লোভী মেলানো দৃ .়তার সাথে করা যায়। বলে দেয় আপনি প্রতি পরিবর্তন করতে চান foo...barকরতে <foo...bar>সুতরাং উদাহরণস্বরূপ এই ইনপুট:

$ cat file
ABC foo DEF bar GHI foo KLM bar NOP foo QRS bar TUV

এই আউটপুট হয়ে উঠতে হবে:

ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV

এটি করার জন্য আপনি foo এবং বারকে স্বতন্ত্র অক্ষরগুলিতে রূপান্তর করেন এবং তারপরে তাদের মধ্যে এই চরিত্রগুলির অবজ্ঞা ব্যবহার করুন:

$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/g; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC <foo DEF bar> GHI <foo KLM bar> NOP <foo QRS bar> TUV

উপরে:

  1. s/@/@A/g; s/{/@B/g; s/}/@C/gরূপান্তর করা হচ্ছে {এবং }স্থানধারীর স্ট্রিংগুলিতে রূপান্তর করা হচ্ছে যা ইনপুটটিতে বিদ্যমান নেই তাই সেই অক্ষরগুলি তখন রূপান্তর করতে fooএবং এগুলিতে উপলভ্য bar
  2. s/foo/{/g; s/bar/}/gরূপান্তরের উদ্দেশ্যে fooএবং barকরতে {এবং }যথাক্রমে
  3. s/{[^{}]*}/<&>/gরূপান্তরিত - আমরা চাই ওপি সম্পাদন করা foo...barহয়<foo...bar>
  4. s/}/bar/g; s/{/foo/gরূপান্তরের উদ্দেশ্যে {এবং }ফিরে fooএবং bar
  5. s/@C/}/g; s/@B/{/g; s/@A/@/g প্লেসহোল্ডার স্ট্রিংগুলিকে তাদের মূল চরিত্রে ফিরিয়ে আনছে।

নোট করুন যে উপরেরটি কোনও নির্দিষ্ট স্ট্রিংটি ইনপুটটিতে উপস্থিত না থাকায় নির্ভর করে না কারণ এটি প্রথম ধাপে এ জাতীয় স্ট্রিং তৈরি করে, এবং এটি কোনও যত্ন নেয় না যে আপনি কোন নির্দিষ্ট রেজিএক্সপেক্সের কোনটি মিল করতে চান কারণ আপনি {[^{}]*}যতবার প্রয়োজন ততবার ব্যবহার করতে পারবেন আপনি চাইছেন এমন আসল ম্যাচটি এবং / অথবা শেড সংখ্যাসূচক ম্যাচ অপারেটরের সাথে আলাদা করতে অভিব্যক্তিতে, উদাহরণস্বরূপ কেবল ২ য় ঘটনাটি প্রতিস্থাপন করতে:

$ sed 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/foo/{/g; s/bar/}/g; s/{[^{}]*}/<&>/2; s/}/bar/g; s/{/foo/g; s/@C/}/g; s/@B/{/g; s/@A/@/g' file
ABC foo DEF bar GHI <foo KLM bar> NOP foo QRS bar TUV

1

এখনো এই উত্তর না দেখেছ তাই এখানে কিভাবে আপনি সঙ্গে এই কাজ করতে পারেন viবা vim:

vi -c '%s/\(http:\/\/.\{-}\/\).*/\1/ge | wq' file &>/dev/null

এটি vi :%sবিশ্বব্যাপী (চলমান g) প্রতিস্থাপন চালায় , প্যাটার্নটি পাওয়া না গেলে ( e) ত্রুটি বাড়ানো থেকে বিরত থাকে , তারপরে ডিস্কে পরিবর্তিত হওয়া পরিবর্তনগুলি বাঁচায়। &>/dev/nullপ্রতিরোধ সংক্ষিপ্তভাবে থেকে GUI পর্দায় ঝলকানি, যা বিরক্তিকর হতে পারে।

আমি viকখনও কখনও সুপার জটিল রেগেক্সসের জন্য ব্যবহার করতে পছন্দ করি, কারণ (1) পার্ল মারা যায় মারা যাচ্ছে, (২) ভিমে খুব উন্নত রেজেক্স ইঞ্জিন রয়েছে, এবং (3) আমি viআমার প্রতিদিনের ব্যবহার সম্পাদনাতে রেজিক্সগুলির সাথে ইতিমধ্যে ঘনিষ্ঠভাবে পরিচিত নথি।


0
echo "/home/one/two/three/myfile.txt" | sed 's|\(.*\)/.*|\1|'

ডান বিরক্ত, আমি এটি অন্য ফোরামে পেয়েছি :)


4
তাই আপনি লোভী ম্যাচ পাবেন: /home/one/two/three/, যদি আপনি অন্য একটি যোগ /মত /home/one/two/three/four/myfile.txtআপনি সাগ্রহে ম্যাচ হবে fourপাশাপাশি: /home/one/two/three/four, প্রশ্ন সম্পর্কে অ লোভী
stefanB


0

এখানে একটি দ্বি-পদক্ষেপের পদ্ধতির এবং অজানা মাধ্যমে আপনি কিছু করতে পারেন:

A=http://www.suepearson.co.uk/product/174/71/3816/  
echo $A|awk '  
{  
  var=gensub(///,"||",3,$0) ;  
  sub(/\|\|.*/,"",var);  
  print var  
}'  

আউটপুট: http://www.suepearson.co.uk

আশা করি এইটি কাজ করবে!


0

আরেকটি সেড সংস্করণ:

sed 's|/[:alnum:].*||' file.txt

এটি /অক্ষরযুক্ত অক্ষরের সাথে মিলিত হয় (সুতরাং অন্য কোনও ফরোয়ার্ড স্ল্যাশ নয়) পাশাপাশি রেখার শেষ অবধি বাকী অক্ষরগুলি। এরপরে এটি এটিকে কোনও কিছুর সাথে প্রতিস্থাপন করে (যেমন। এটি মুছে ফেলে))


1
আমার ধারণা এটি হওয়া উচিত "[[:alnum:]]", না "[:alphanum:]"
oli_arborum
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.