বাশে সাবস্ট্রাকিং উত্তোলন করুন


727

ফর্মটিতে একটি ফাইলের নাম দেওয়া হয়েছে someletters_12345_moreleters.ext, আমি 5 টি সংখ্যা বের করতে এবং এটিকে একটি ভেরিয়েবলের মধ্যে রাখতে চাই।

সুতরাং পয়েন্টটি জোর দেওয়ার জন্য, আমার কাছে এক্স নাম্বার সহ একটি ফাইলের নাম আছে তারপরে পাঁচটি অঙ্কের ক্রম দুটি একক আন্ডারস্কোর দ্বারা বেষ্টিত থাকে তবে এক্স সংখ্যার অক্ষরের আরও একটি সেট। আমি 5 সংখ্যার নম্বর নিতে এবং এটি একটি ভেরিয়েবলের মধ্যে রাখতে চাই।

এটি বিভিন্ন উপায়ে সম্পন্ন হতে পারে তার সংখ্যার প্রতি আমি খুব আগ্রহী।


5
জেবির উত্তর স্পষ্টতই ভোটে জিতেছে - গ্রহণযোগ্য উত্তর বদলের সময় কী?
জেফ

3
উত্তরটি বেশিরভাগই আপনার প্রশ্নের উত্তর বলে মনে হচ্ছে না কারণ প্রশ্নটি দ্ব্যর্থক। "আমার কাছে এক্স সংখ্যার অক্ষরযুক্ত একটি ফাইল নাম আছে তারপরে উভয় পাশের একক আন্ডারস্কোর দ্বারা বেষ্টিত পাঁচ অঙ্কের ক্রম এবং তার পরে x সংখ্যার অক্ষরের একটি সেট" । যে সংজ্ঞা abc_12345_def_67890_ghi_defদ্বারা একটি বৈধ ইনপুট। আপনি কি হতে চান? ধরা যাক এখানে কেবল একটি 5 অঙ্কের ক্রম রয়েছে। আপনি এখনও আছে abc_def_12345_ghi_jklবা 1234567_12345_1234567অথবা 12345d_12345_12345eইনপুট আপনার সংজ্ঞা উপর ভিত্তি করে এবং উত্তর অধিকাংশ নীচের এই হ্যান্ডেল করা হবে না বৈধ ইনপুট হিসাবে।
gman

2
এই প্রশ্নের একটি উদাহরণ ইনপুট রয়েছে যা খুব নির্দিষ্ট। তার কারণে, এটি এই নির্দিষ্ট ক্ষেত্রে (কেবলমাত্র অঙ্কগুলি, একই _ডিলিমিটার, ইনপুট যাতে কেবলমাত্র একবারে টার্গেট স্ট্রিং থাকে ইত্যাদি) সুনির্দিষ্ট উত্তর পেয়েছে । সেরা (অধিকাংশ জেনেরিক ও দ্রুততম) উত্তর 10 বছর, শুধুমাত্র 7 upvotes শত শত যখন অন্যান্য সীমিত উত্তর আছে পরে আছে। আমাকে বিকাশকারীদের প্রতি বিশ্বাস হারাতে বাধ্য করে 😞
ড্যান ড্যাসক্লেস্কু

উত্তর:


691

ব্যবহার কাটা :

echo 'someletters_12345_moreleters.ext' | cut -d'_' -f 2

আরও জেনেরিক:

INPUT='someletters_12345_moreleters.ext'
SUBSTRING=$(echo $INPUT| cut -d'_' -f 2)
echo $SUBSTRING

1
আরও সাধারণ উত্তর হ'ল আমি যা খুঁজছিলাম, ধন্যবাদ
বেরেক ব্রায়ান

71
-ফ পতাকাটি 1-ভিত্তিক সূচক নেয়, 0-ভিত্তিক সূচকগুলির পরিবর্তে একজন প্রোগ্রামার ব্যবহৃত হত।
ম্যাথু জি

2
ইনপুট = someletters_12345_moreleters.ext সাবস্ট্রিং = $ ($ ইনপুট echo | কাটা -d'_ '-f 2) $ সাবস্ট্রিং echo
মনি দীপক

3
echoআপনার ভেরিয়েবলগুলিতে অনিয়মিত সাদা স্থান বা শেল মেটাচার্যাক্টর থাকতে পারে না তা আপনি নিশ্চিত না জানলে আপনার পক্ষে যুক্তির আশেপাশে ডাবল উদ্ধৃতিগুলি সঠিকভাবে ব্যবহার করা উচিত । আরও দেখুন stackoverflow.com/questions/10067266/...
tripleee

'-F' এর পরে '2' নাম্বারটি শেলটি স্ট্রিংয়ের দ্বিতীয় সেটটি বের করতে বলা হয়।
সানডুন

1084

যদি এক্স ধ্রুব থাকে তবে নিম্নলিখিত প্যারামিটার সম্প্রসারণটি স্ট্রিংয়ের নিষ্কাশন সম্পাদন করে:

b=${a:12:5}

যেখানে 12 অফসেট (শূন্য-ভিত্তিক) এবং 5 দৈর্ঘ্য

যদি অঙ্কগুলির চারপাশের আন্ডারস্কোরগুলি কেবল ইনপুটটিতে থাকে তবে আপনি দুটি ধাপে উপসর্গ এবং প্রত্যয় (যথাক্রমে) কেটে ফেলতে পারেন:

tmp=${a#*_}   # remove prefix ending in "_"
b=${tmp%_*}   # remove suffix starting with "_"

যদি আরও আন্ডারস্কোর থাকে তবে এটি সম্ভবত সম্ভাব্য, তবে আরও জটিল। যদি কেউ একক অভিব্যক্তিতে উভয় প্রসারকে কীভাবে সম্পাদন করতে জানেন তবে আমিও তা জানতে চাই।

উপস্থাপিত উভয় সমাধান খাঁটি বাশ, কোনও প্রক্রিয়া জড়িত নেই, সুতরাং খুব দ্রুত।


18
@SpencerRathbun bash: ${${a#*_}%_*}: bad substitutionআমার গনুহ ব্যাশ 4.2.45 উপর।
জেবি।

2
@ জনিবি, অতীতে কিছু সময় কাজ করেছিল। আমার সহকর্মীরা আমাকে বলেছে এটি থেমে গেছে, এবং তারা এটিকে সিড কমান্ড বা অন্য কিছু হিসাবে পরিবর্তন করেছে। ইতিহাসে এটি তাকিয়ে আমি এটি একটি shস্ক্রিপ্টে চালাচ্ছিলাম যা সম্ভবত ড্যাশ ছিল। এই মুহুর্তে আমি এটি আর কাজ করতে পারি না।
স্পেন্সার রথবুন

22
জেবি, আপনার পরিষ্কার করা উচিত যে "12" অফসেট (শূন্য-ভিত্তিক) এবং "5" দৈর্ঘ্য। এছাড়াও, @ gontard এর লিঙ্কের জন্য +1 যা এটিকে সব কিছু দিয়ে দেয়!
ডক্টর জে

1
এটি "sh run.sh" হিসাবে স্ক্রিপ্টের ভিতরে চলাকালীন, কেউ খারাপ সাবস্টিটিউশন ত্রুটি পেতে পারে। এটি এড়াতে, run.sh (chmod + x run.sh) এর জন্য অনুমতি পরিবর্তন করুন এবং তারপরে "./run.sh" হিসাবে স্ক্রিপ্টটি চালান
অঙ্কুর

2
অফসেট প্যারামটি নেতিবাচকও হতে পারে, বিটিডাব্লু। এটিকে কোলনটিতে আঠা না দেওয়ার জন্য আপনাকে কেবল খেয়াল রাখতে হবে, বা বাশ এটি :-"ডিফল্ট মান ব্যবহার করুন" বিকল্প হিসাবে ব্যাখ্যা করবে । সুতরাং ${a: -12:5}শেষ থেকে 5 টি অক্ষর 12 টি অক্ষর ${a: -12:-5}এবং শেষ -12 এবং শেষ -5 এর মধ্যে 7 অক্ষর উপার্জন করে।
জেবি।

96

জেনেরিক সমাধান যেখানে নম্বরটি ফাইলের নামের যে কোনও জায়গায় থাকতে পারে, এই জাতীয় ক্রমের প্রথমটি ব্যবহার করে:

number=$(echo $filename | egrep -o '[[:digit:]]{5}' | head -n1)

ভেরিয়েবলের হুবহু অংশ বের করার আর একটি সমাধান:

number=${filename:offset:length}

যদি আপনার ফাইলের নামটিতে সর্বদা ফর্ম্যাট থাকে তবে stuff_digits_...আপনি awk ব্যবহার করতে পারেন:

number=$(echo $filename | awk -F _ '{ print $2 }')

তবুও অঙ্কগুলি বাদে সবকিছু মুছে ফেলার আরেকটি সমাধান use

number=$(echo $filename | tr -cd '[[:digit:]]')

2
আমি যদি ফাইলের শেষ লাইন থেকে অঙ্ক / শব্দটি বের করতে চাই তবে কী হবে।
এ সাহারা

92

শুধু ব্যবহার করার চেষ্টা করুন cut -c startIndx-stopIndx


2
স্টার্ট ইন্ডেক্স-লাস্ট ইন্ডেক্স - 1 এর মতো কিছু আছে কি?
নিক্লাস

1
@ নিক্লাস ইন ব্যাশ, প্রলি startIndx-$((lastIndx-1))
বাদামী .2179

3
start=5;stop=9; echo "the rain in spain" | cut -c $start-$(($stop-1))
বাদামী.2179

1
সমস্যাটি হ'ল ইনপুটটি গতিশীল যেহেতু আমি পাইপটি এটি পেতে পাই তাই এটি মূলত। git log --oneline | head -1 | cut -c 9-(end -1)
নিক্লাস

line=গিট লগ - অন লাইন হিসাবে দুটি ভাগে বিভক্ত হলে কাটা দিয়ে এটি করা যায় শিরোনাম -1` && প্রতিধ্বনি $ লাইন | কাটা -c 9 - $ (($ {# লাইন} -1)) `কিন্তু এই বিশেষ ক্ষেত্রে, ভালো হতে পারে ব্যবহার করার sed যেমনgit log --oneline | head -1 | sed -e 's/^[a-z0-9]* //g'
brown.2179

34

যদি কেউ আরও কঠোর তথ্য চায় তবে আপনি এটি ম্যান ব্যাশেও এটি অনুসন্ধান করতে পারেন

$ man bash [press return key]
/substring  [press return key]
[press "n" key]
[press "n" key]
[press "n" key]
[press "n" key]

ফলাফল:

$ {পরামিতি: অফসেট}
       $ {পরামিতি: অফসেট: দৈর্ঘ্য}
              সাবস্ট্রিং প্রসার। এর দৈর্ঘ্যের অক্ষর পর্যন্ত প্রসারিত হয়
              অফসেট দ্বারা নির্দিষ্ট করা অক্ষর থেকে শুরু প্যারামিটার। যদি
              দৈর্ঘ্য বাদ দেওয়া হয়, প্যারামিটার স্টার্টিংয়ের প্রসারিত হয় ‐
              অফসেট দ্বারা সুনির্দিষ্ট চরিত্রটিতে ing। দৈর্ঘ্য এবং অফসেট হয়
              পাটিগণিতের এক্সপ্রেশন (নীচে কৃত্রিম মূল্যায়ন দেখুন)। যদি
              অফসেট শূন্যের চেয়ে কম সংখ্যায় মূল্যায়ন করে, মান ব্যবহৃত হয়
              প্যারামিটারের মান শেষে থেকে অফসেট হিসাবে। পাটীগণিত
              a দিয়ে শুরু হওয়া এক্সপ্রেশনগুলি অবশ্যই হোয়াইটস্পেস দ্বারা পৃথক করা উচিত
              পূর্ববর্তী থেকে: ব্যবহার ডিফল্ট থেকে পৃথক করা
              মান সম্প্রসারণ। দৈর্ঘ্য যদি এর চেয়ে কম সংখ্যায় মূল্যায়ন করে
              শূন্য, এবং প্যারামিটারটি @ নয় এবং কোনও সূচকযুক্ত বা সহযোগী নয়
              অ্যারে, এটি মান শেষে থেকে একটি অফসেট হিসাবে ব্যাখ্যা করা হয়
              অনেকগুলি অক্ষরের পরিবর্তে প্যারামিটার এবং বিস্তৃতি
              সায়ন দুটি অফসেটের মধ্যে অক্ষর। যদি প্যারামিটার হয়
              @, ফলাফলটি দৈর্ঘ্যের অবস্থানগত পরামিতিগুলি অফ থেকে শুরু হবে ‐
              সেট। যদি প্যারামিটারটি একটি সূচকযুক্ত অ্যারে নাম হয় তবে @ বা সাবস্ক্রিপড
              *, ফলাফলটি অ্যারের দৈর্ঘ্যের সদস্যদের সাথে শুরু হয়
              $ {প্যারামিটার [অফসেট]}। একটি নেতিবাচক অফসেট আপেক্ষিকভাবে নেওয়া হয়
              নির্দিষ্ট অ্যারের সর্বাধিক সূচকের চেয়ে বড়। সাব-
              একটি সাহসী অ্যারে প্রয়োগ স্ট্রিং প্রসারণ unde‐ উত্পাদন করে
              জরিমানা ফলাফল। মনে রাখবেন যে একটি নেতিবাচক অফসেটটি পৃথক করা উচিত
              বিভ্রান্ত হওয়া এড়াতে কমপক্ষে একটি জায়গা দিয়ে কোলন থেকে
              সাথে: - সম্প্রসারণ। সাবস্ট্রিং ইনডেক্সিং শূন্য-ভিত্তিক unless
              অবস্থানগত পরামিতি ব্যবহৃত হয়, সেক্ষেত্রে সূচীকরণ
              ডিফল্ট হিসাবে 1 এ শুরু হয়। যদি অফসেট 0 হয়, এবং অবস্থানগত হয়
              প্যারামিটার ব্যবহার করা হয়, $ 0 তালিকার সাথে উপসর্গ করা হয়।

2
নেতিবাচক মানগুলির সাথে একটি অত্যন্ত গুরুত্বপূর্ণ ক্যাভিয়েট যেমন উপরে বর্ণিত হয়েছে: গাণিতিক এক্সপ্রেশনগুলি - এর সাথে শুরু হয়ে গ্লোথস্পেস দিয়ে পৃথক করতে হবে: ডিফল্ট মান ব্যবহারের ব্যবহার থেকে আলাদা করতে হবে। সুতরাং ${var: -4}
কোনও ভেরির

26

আমি এটি কীভাবে করব তা এখানে:

FN=someletters_12345_moreleters.ext
[[ ${FN} =~ _([[:digit:]]{5})_ ]] && NUM=${BASH_REMATCH[1]}

ব্যাখ্যা:

ব্যাশ-নির্দিষ্ট:

নিয়মিত এক্সপ্রেশন (আরই): _([[:digit:]]{5})_

  • _ স্ট্রিং মেলানোর জন্য সীমানা নির্ধারণ / অ্যাঙ্কর ম্যাচিংয়ের জন্য আক্ষরিক
  • () ক্যাপচার গ্রুপ তৈরি করুন
  • [[:digit:]] একটি চরিত্র শ্রেণি, আমার মনে হয় এটি নিজের জন্য কথা বলে
  • {5} মানে পূর্বের অক্ষরের ঠিক পাঁচটি, শ্রেণি (এই উদাহরণ হিসাবে), বা গোষ্ঠীটি অবশ্যই মিলবে

ইংরাজীতে, আপনি এটির এরূপ আচরণের কথা ভাবতে পারেন: FNস্ট্রিংটি চরিত্র অনুসারে পুনরুক্তি করা হয় যতক্ষণ না আমরা দেখতে পেলাম _যে ক্যাপচার গ্রুপটি খোলা আছে এবং আমরা পাঁচটি অঙ্কের সাথে মেলে চেষ্টা করি। যদি সেই মিলটি এই স্থানে সফল হয় তবে ক্যাপচার গ্রুপটি ট্র্যাশড পাঁচটি অঙ্ক সংরক্ষণ করে। পরবর্তী অক্ষরটি যদি একটি হয় _তবে শর্তটি সফল হয়, ক্যাপচার গ্রুপটি উপলব্ধ করা হয় BASH_REMATCHএবং পরবর্তী NUM=বিবৃতিটি কার্যকর করতে পারে। যদি মিলের কোনও অংশ ব্যর্থ হয় তবে সংরক্ষিত বিবরণগুলি নিষ্পত্তি করা হয় এবং অক্ষর প্রক্রিয়াজাতকরণ দ্বারা অক্ষর প্রক্রিয়াটি পরে চলতে থাকে _। উদাহরণস্বরূপ, যদি FNযেখানে _1 _12 _123 _1234 _12345_থাকে তবে এটি কোনও মিল খুঁজে পাওয়ার আগে চারটি ভুয়া শুরু হবে।


3
এটি একটি জেনেরিক উপায় যা আপনার যেমন একাধিক জিনিস বের করার প্রয়োজন হয় তার পরেও কাজ করে।
জাবেদিয়া 49

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

1
এই উত্তরটি অপরাধমূলকভাবে অবহেলিত।
চ্যানার

এটা অসাধারণ! আমি আমার পরিস্থিতির জন্য বিভিন্ন স্টার্ট / স্টপ ডিলিমিটারগুলি (_ _ প্রতিস্থাপন করুন) এবং পরিবর্তনশীল দৈর্ঘ্যের সংখ্যাগুলি (। {5} এর জন্য) ব্যবহার করার জন্য এটি রূপান্তর করেছি। কেউ কি এই কালো যাদুটি ভেঙে ব্যাখ্যা করতে পারে?
পল

1
@ পল আমি আমার উত্তরে আরও বিশদ যুক্ত করেছি। আশা করি এইটি কাজ করবে.
নিকরোবোট

21

আমি আশ্চর্য হয়েছি যে এই বিশুদ্ধ বাশ সমাধানটি আসে নি:

a="someletters_12345_moreleters.ext"
IFS="_"
set $a
echo $2
# prints 12345

আপনি সম্ভবত আইএফএসের আগে বা তার unset IFSপরে মূল্যটি পুনরায় সেট করতে চান !


1
এটি খাঁটি বাশ সমাধান নয়, আমি মনে করি এটি খাঁটি শেল (/ বিন / শ) এ কাজ করে
কেইন

5
+1 আপনি আনসেট IFSএবং অবস্থানগত পরামিতিগুলি এড়াতে অন্য কোনও উপায়ে এটি লিখতে পারেন :IFS=_ read -r _ digs _ <<< "$a"; echo "$digs"
কোজিরো

2
এটি পথের নাম সম্প্রসারণ সাপেক্ষে! (সুতরাং এটি ভেঙে গেছে)
gniourf_gniourf

20

জোরের জবাবের উপর ভিত্তি করে তৈরি করা (যা আমার পক্ষে কাজ করে না):

substring=$(expr "$filename" : '.*_\([^_]*\)_.*')

12
নিয়মিত এক্সপ্রেশন হ'ল আসল চুক্তি যখন আপনার কিছু জটিল হয় এবং কেবল আন্ডারস্কোরগুলি গণনা করা হয় না cut
আলেকসান্দ্র লেভুকুক

12

প্রয়োজনীয়তা অনুসরণ করে

আমার এক্স নাম্বার সহ একটি ফাইল নাম রয়েছে তারপরে পাঁচটি অঙ্কের ক্রম দুটি একক আন্ডারস্কোর দ্বারা বেষ্টিত এবং তারপরে x সংখ্যার অক্ষরের আরও একটি সেট। আমি 5 সংখ্যার নম্বর নিতে এবং এটি একটি ভেরিয়েবলের মধ্যে রাখতে চাই।

আমি কিছু grepউপায় খুঁজে পেয়েছি যা কার্যকর হতে পারে:

$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]+" 
12345

বা আরও ভাল

$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]{5}" 
12345

এবং তারপরে -Poসিনট্যাক্স সহ:

$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d+' 
12345

অথবা আপনি যদি এটি ঠিক 5 টি অক্ষরকে ফিট করতে চান:

$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d{5}' 
12345

অবশেষে, এটিকে ভেরিয়েবলে সংরক্ষণ করার জন্য কেবল var=$(command)সিনট্যাক্স ব্যবহার করা দরকার ।


2
আমি বিশ্বাস করি আজকাল egrep ব্যবহার করতে কোন প্রয়োজন নেই, কমান্ড নিজেই আপনাকে সতর্ক করে: Invocation as 'egrep' is deprecated; use 'grep -E' instead। আমি আপনার উত্তর সম্পাদনা করেছি।
নিউরোট্রান্সমিটার

11

যদি আমরা এই ধারণার দিকে মনোনিবেশ করি:
"(এক বা একাধিক) সংখ্যা"

সংখ্যাগুলি বের করতে আমরা বেশ কয়েকটি বাহ্যিক সরঞ্জাম ব্যবহার করতে পারি।
আমরা খুব সহজেই অন্য সমস্ত অক্ষরগুলি মুছে ফেলতে পারি, হয় সেড বা টিআর:

name='someletters_12345_moreleters.ext'

echo $name | sed 's/[^0-9]*//g'    # 12345
echo $name | tr -c -d 0-9          # 12345

তবে যদি $ নামটিতে বেশ কয়েকটি সংখ্যা থাকে তবে উপরেরটি ব্যর্থ হবে:

যদি "নাম = সামলেটারগুলি 232345_মোরলেটারগুলি 2323_end.ext", তবে:

echo $name | sed 's/[^0-9]*//g'    # 12345323
echo $name | tr -c -d 0-9          # 12345323

আমাদের নিয়মিত এক্সপ্রেশন (রেজেক্স) ব্যবহার করা দরকার।
সেড এবং পারলে কেবল প্রথম রান (12345 নয় 323) নির্বাচন করতে:

echo $name | sed 's/[^0-9]*\([0-9]\{1,\}\).*$/\1/'
perl -e 'my $name='$name';my ($num)=$name=~/(\d+)/;print "$num\n";'

তবে আমরা এটি সরাসরি ব্যাশে করতে পারি (1) :

regex=[^0-9]*([0-9]{1,}).*$; \
[[ $name =~ $regex ]] && echo ${BASH_REMATCH[1]}

এটি আমাদের
অন্য কোনও পাঠ্য / অক্ষর দ্বারা ঘিরে থাকা কোনও দৈর্ঘ্যের অঙ্কের প্রথম রান সংগ্রহ করতে দেয় ।

দ্রষ্টব্য : regex=[^0-9]*([0-9]{5,5}).*$;মিলবে মাত্র 5 ডিজিটের রানের সাথে। :-)

(1) : প্রতিটি সংক্ষিপ্ত পাঠ্যের জন্য একটি বাহ্যিক সরঞ্জাম কল করার চেয়ে দ্রুত। শেডের ভিতরে সমস্ত প্রসেসিং করা বা বড় ফাইলগুলির জন্য awk চেয়ে দ্রুত নয়।


10

কোনও উপ-প্রক্রিয়া ছাড়াই আপনি পারবেন:

shopt -s extglob
front=${input%%_+([a-zA-Z]).*}
digits=${front##+([a-zA-Z])_}

এর খুব ছোট একটি রূপটিও ksh93 এ কাজ করবে।


9

এখানে একটি উপসর্গ-প্রত্যয় সমাধান (জেবি এবং ড্যারন প্রদত্ত সমাধানগুলির অনুরূপ) যা অঙ্কগুলির প্রথম ব্লকের সাথে মেলে এবং আশেপাশের আন্ডারস্কোরগুলির উপর নির্ভর করে না:

str='someletters_12345_morele34ters.ext'
s1="${str#"${str%%[[:digit:]]*}"}"   # strip off non-digit prefix from str
s2="${s1%%[^[:digit:]]*}"            # strip off non-digit suffix from s1
echo "$s2"                           # 12345

7

আমি sedরেজেক্স গ্রুপগুলির সাথে ডিল করার সামর্থ্যকে ভালবাসি :

> var="someletters_12345_moreletters.ext"
> digits=$( echo $var | sed "s/.*_\([0-9]\+\).*/\1/p" -n )
> echo $digits
12345

একটি সামান্য আরো সাধারণ বিকল্প হবে না অনুমান করা আপনি একটি আন্ডারস্কোর আছে _অত: পর উদাহরণস্বরূপ সমস্ত অ-সংখ্যার আপনি আপনার ক্রম সামনে পেতে stripping বন্ধ জন্য আপনার ডিজিটের ক্রম শুরু উপলক্ষে: s/[^0-9]\+\([0-9]\+\).*/\1/p


> man sed | grep s/regexp/replacement -A 2
s/regexp/replacement/
    Attempt to match regexp against the pattern space.  If successful, replace that portion matched with replacement.  The replacement may contain the special  character  &  to
    refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.

এ সম্পর্কে আরও, যদি আপনি রিজেক্সপসে খুব বেশি আত্মবিশ্বাসী না হন:

  • s _স_স্টাস্টিউটের জন্য
  • [0-9]+ 1+ সংখ্যার সাথে মেলে
  • \1 রেজেক্স আউটপুটটির গ্রুপ এন 1 এর লিঙ্কগুলি (গ্রুপ 0 পুরো ম্যাচ, গ্রুপ 1 এই ক্ষেত্রে বন্ধনীগুলির মধ্যে ম্যাচ)
  • p পতাকা _p_rinting এর জন্য

সকল বেরিয়ে \সেখানে করতে হয় sedএর regexp প্রক্রিয়াকরণ হবে।


6

আপনার উত্তরটি আপনার স্ট্রিংয়ের বাইরে যা চান তার উপর আমার উত্তরটির আরও নিয়ন্ত্রণ থাকবে। আপনি 12345আপনার স্ট্রিং থেকে কীভাবে নিষ্কাশন করতে পারবেন তার কোড এখানে

str="someletters_12345_moreleters.ext"
str=${str#*_}
str=${str%_more*}
echo $str

আপনি আরও কিছু কার্যকর করতে সক্ষম হন যদি আপনি এমন কিছু নিষ্কাশন করতে চান যার মতো abcকোনও চরিত্র _বা বিশেষ চরিত্রের মতো বা থাকে -। উদাহরণস্বরূপ: যদি আপনার স্ট্রিংটি এর মতো হয় এবং আপনি তার someletters_আগে এবং আগের যা কিছু চান তা চাই _moreleters.ext:

str="someletters_123-45-24a&13b-1_moreleters.ext"

আমার কোড দিয়ে আপনি ঠিক কী চান তা উল্লেখ করতে পারেন। ব্যাখ্যা:

#*এটি ম্যাচিং কী সহ পূর্ববর্তী স্ট্রিংটি সরিয়ে ফেলবে। এখানে আমরা যে কীটি উল্লেখ করেছি তা হ'ল _ %এটি মেলানো কী সহ নিম্নলিখিত স্ট্রিংটি সরিয়ে ফেলবে। এখানে আমরা যে কীটি উল্লেখ করেছি তা হ'ল '_মোর *'

নিজে কিছু পরীক্ষা-নিরীক্ষা করুন এবং এটি আপনাকে আকর্ষণীয় মনে হবে।


6

প্রদত্ত পরীক্ষা.টিএসটিএসটি হ'ল "এবিসিডিএফজিআইজিএইচকেএমএমওপিকিআরএসটিইউডাব্লুএক্সএইচজেড" যুক্ত একটি ফাইল

cut -b19-20 test.txt > test1.txt # This will extract chars 19 & 20 "ST" 
while read -r; do;
> x=$REPLY
> done < test1.txt
echo $x
ST

এটি সেই নির্দিষ্ট ইনপুটটির জন্য অত্যন্ত নির্দিষ্ট। সাধারণ প্রশ্নের একমাত্র সাধারণ সমাধান (যা ওপিকে জিজ্ঞাসা করা উচিত ছিল) হ'ল একটি রেজিপেক্স ব্যবহার করা
ড্যান ড্যাসক্লেস্কু

3

ঠিক আছে, খালি স্ট্রিং সহ খাঁটি প্যারামিটার সাবস্টিটিউশনটি এখানে যায়। ক্যাভেটটি হ'ল আমি কিছু সংখ্যককে সংজ্ঞায়িত করেছি অক্ষর এবং মোরলেটারকে কেবল অক্ষর হিসাবে । যদি তারা বর্ণমালা হয় তবে এটি যেমন হয় তেমন কাজ করবে না।

filename=someletters_12345_moreletters.ext
substring=${filename//@(+([a-z])_|_+([a-z]).*)}
echo $substring
12345

2
দুর্দান্ত তবে কমপক্ষে bash v4 দরকার
ওলিব্রে

2

পিএইচপি-তে সাবস্ট্রাস্টের ('abcdefg', 2-1, 3) এর অনুরূপ:

echo 'abcdefg'|tail -c +2|head -c 3

এটি এই ইনপুটটির জন্য অত্যন্ত নির্দিষ্ট। সাধারণ প্রশ্নের একমাত্র সাধারণ সমাধান (যা ওপিকে জিজ্ঞাসা করা উচিত ছিল) হ'ল একটি রেজিপেক্স ব্যবহার করা
ড্যান ড্যাসকলেসকু

1

বাশ বিল্টিন 'এক্সপ্রেস' কমান্ডটি এখানে রয়েছে:

INPUT="someletters_12345_moreleters.ext"  
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)_.*' `  
echo $SUBSTRING

4
exprএকটি অন্তর্নির্মিত না।
gniourf_gniourf

1
=~অপারেটর দ্বারা সমর্থিত আলোকে এটি প্রয়োজনীয়ও নয় [[
চিপনার

1

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

host:/tmp$ asd=someletters_12345_moreleters.ext 
host:/tmp$ echo `expr $asd : '.*_\(.*\)_'`
12345
host:/tmp$ 

আমি এটি এম্বেড থাকা সিস্টেমে মিলিসেকেন্ড রেজোলিউশন পেতে ব্যবহার করেছি যার জন্য এখনও% N নেই:

set `grep "now at" /proc/timer_list`
nano=$3
fraction=`expr $nano : '.*\(...\)......'`
$debug nano is $nano, fraction is $fraction

1

একটি বাশ সমাধান:

IFS="_" read -r x digs x <<<'someletters_12345_moreleters.ext'

এটি ক্লোবারকে একটি ভেরিয়েবল বলে x। ভেরটি ভারে xপরিবর্তিত হতে পারে _

input='someletters_12345_moreleters.ext'
IFS="_" read -r _ digs _ <<<"$input"

1

জেএস এবং জাভা বাস্তবায়নের অনুরূপ ইনক্লুসিভ শেষ। আপনি যদি এটি না চান তবে +1 সরান।

substring() {
    local str="$1" start="${2}" end="${3}"

    if [[ "$start" == "" ]]; then start="0"; fi
    if [[ "$end"   == "" ]]; then end="${#str}"; fi

    local length="((${end}-${start}+1))"

    echo "${str:${start}:${length}}"
} 

উদাহরণ:

    substring 01234 0
    01234
    substring 012345 0
    012345
    substring 012345 0 0
    0
    substring 012345 1 1
    1
    substring 012345 1 2
    12
    substring 012345 0 1
    01
    substring 012345 0 2
    012
    substring 012345 0 3
    0123
    substring 012345 0 4
    01234
    substring 012345 0 5
    012345

আরও উদাহরণ কল:

    substring 012345 0
    012345
    substring 012345 1
    12345
    substring 012345 2
    2345
    substring 012345 3
    345
    substring 012345 4
    45
    substring 012345 5
    5
    substring 012345 6

    substring 012345 3 5
    345
    substring 012345 3 4
    34
    substring 012345 2 4
    234
    substring 012345 1 3
    123

আপনি স্বাগত জানাই।

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