'কাটা' ব্যবহার করে শেষ ক্ষেত্রটি কীভাবে সন্ধান করবেন


310

ছাড়া ব্যবহার sedবা awk, শুধুমাত্র cut , কিভাবে আমি গত ক্ষেত্র যখন ক্ষেত্র সংখ্যা অজানা বা প্রতি লাইন দিয়ে পরিবর্তন হয় পেতে পারি?


8
আপনি cutকমান্ড প্রেমে আছেন :)? অন্য কোনও লিনাক্স আদেশ দেয় না কেন?
জয়েশ ভোই

7
ছাড়া sedবা awk: perl -pe 's/^.+\s+([^\s]+)$/$1/'
জর্ডানম


4
@ মাস্টারলিয়ন অনেক সময় সমস্যার কোনও তারতম্যের সমাধান খুঁজতে লোকেরা একটি প্রশ্ন পড়ে read এইটি এমন মিথ্যা ভিত্তি দিয়ে শুরু হয় যা cutএমন কিছুকে সমর্থন করে যা এটি করে না। তবে আমি ভেবেছিলাম এটি কার্যকর ছিল, এটি পাঠককে এমন কোড বিবেচনা করতে বাধ্য করে যা অনুসরণ করা সহজ। আমি একটি দ্রুত, ব্যবহার করা সহজ উপায় চেয়েছিলেন cutজন্য একাধিক syntaxes ব্যবহার করতে ছাড়াই awk, grep, sed, ইত্যাদি revজিনিস কৌতুক করেনি; খুব মার্জিত, এবং এমন কিছু যা আমি কখনই বিবেচনা করি নি (এমনকি অন্যান্য পরিস্থিতিতে ছদ্মবেশী হলেও)। আমি অন্যান্য উত্তরগুলি থেকে অন্যান্য পদ্ধতির পড়াও পছন্দ করি।
বিউজর

3
এখানে আসল জীবনের এক সমস্যা: আমি একটি উত্স ট্রিতে সমস্ত বিভিন্ন ফাইল এক্সটেনশন খুঁজে পেতে চাই, যার সাথে একটি .gitattributes ফাইল আপডেট করতে পারি। সুতরাং find | cut -d. -f<last>প্রাকৃতিক প্রবণতা
studog

উত্তর:


679

আপনি এরকম কিছু চেষ্টা করতে পারেন:

echo 'maps.google.com' | rev | cut -d'.' -f 1 | rev

ব্যাখ্যা

  • rev "map.google.com.com" হিসাবে বিপরীত হয় moc.elgoog.spam
  • cut ডিলিমিটার হিসাবে বিন্দু (অর্থাৎ '।') ব্যবহার করে এবং প্রথম ক্ষেত্রটি বেছে নেয় যা moc
  • শেষ অবধি, আমরা এটি পেতে আবার বিপরীত com

6
এটি কেবল ব্যবহার করছে না cutএটি ছাড়া sedবা এটি awk
জয়েশ ভোই

7
@ টম ওপি গত কয়েক ঘন্টার মধ্যে এর চেয়ে আরও বেশি প্রশ্ন জিজ্ঞাসা করেছে। ওপির সাথে আমাদের মিথস্ক্রিয়ার ভিত্তিতে আমরা জানি যে জাজ / শেড / ইত্যাদি। তার হোম ওয়ার্কে অনুমোদিত নয় তবে পুনর্বিবেচনার একটি রেফারেন্স তৈরি করা হয়নি। সুতরাং এটি একটি শটের জন্য মূল্য ছিল
জেডফক্সাস

4
@zfus আমি দেখছি revপরে অন্য একটি আটকাতে চাই ।
টম

17
ডাবল revদুর্দান্ত আদর্শ!
ফোর্ড গুও

6
দুর্দান্ত, সাধারণ, নিখুঁত, ব্যাখ্যাটির জন্যও ধন্যবাদ - পাইপযুক্ত কমান্ডগুলির দীর্ঘ শৃঙ্খলে প্রতিটি পদক্ষেপের জন্য যথেষ্ট লোকজন ব্যাখ্যা করছে না
পিট

128

একটি প্যারামিটার বিস্তৃতি ব্যবহার করুন। এটি কোনও ধরণের বাহ্যিক কমান্ডের চেয়ে অনেক বেশি দক্ষ, cut(বা grep) অন্তর্ভুক্ত।

data=foo,bar,baz,qux
last=${data##*,}

ব্যাশে নেটিভ স্ট্রিং ম্যানিপুলেশনের পরিচিতির জন্য বাশফ্যাঙ্ক # 100 দেখুন ।


3
@ ইরউনওয়েসেলস: কারণ বাশ আসলেই ধীর। পাইপলাইনগুলি চালাতে বাশ ব্যবহার করুন, বাল্কে ডেটা প্রক্রিয়াকরণ করতে নয়। আমি বলতে চাইছি, শেল ভেরিয়েবলের মধ্যে ইতিমধ্যে যদি আপনার এক লাইনের পাঠ্য থাকে বা আপনি while IFS= read -ra array_var; do :;done <(cmd)কয়েকটি লাইন প্রসেস করতে চান তবে এটি দুর্দান্ত । তবে বড় ফাইলের জন্য রেভ | কাট | রেভ সম্ভবত দ্রুত! (এবং অবশ্যই বিশ্রী এর চেয়ে দ্রুততর হবে))
পিটার কর্ডেস

2
@ পিটারকর্ডস, একটি বড় ফাইলের জন্য অ্যাডাব্লিক দ্রুত হবে, নিশ্চিত, তবে ধ্রুবক-ফ্যাক্টর স্টার্টআপ ব্যয়গুলি কাটিয়ে উঠতে মোটামুটি ইনপুট লাগে। (খসখের নিকটে পারফরম্যান্স সহ ksh93 - এর মতো শেলও রয়েছে, যেখানে এই উত্তরে দেওয়া বাক্য গঠন বৈধ থাকে; ব্যাশ ব্যতিক্রমীভাবে সুগঠিত, তবে এটি একমাত্র বিকল্পের কাছেও নেই)।
চার্লস ডাফি

1
ধন্যবাদ @ পিটারকর্ডস; যথারীতি আমি অনুমান করি যে প্রতিটি সরঞ্জামটির ব্যবহারের ক্ষেত্রে রয়েছে।
এরউইন ওয়েসেলস

1
এটি কোনও bashস্ক্রিপ্টের অভ্যন্তরে একক ভেরিয়েবলটি ছাঁটাই করার সবচেয়ে দ্রুত এবং সর্বাধিক সংক্ষিপ্ত উপায় (ধরে নিলে আপনি ইতিমধ্যে কোনও bashস্ক্রিপ্ট ব্যবহার করছেন )। বাহ্যিক কিছু বলার দরকার নেই।
কেন শার্প

1
@ বেলামিপুর, ... তবে আপনি যে কোনও ওএস ব্যবহার করে যা এটি সরবরাহ করে rev তার সাথে সুনির্দিষ্ট - এটি সমস্ত ইউএনআইএক্স সিস্টেমের মধ্যে মানক নয়। কমান্ড এবং ইউটিলিটিগুলিতে পসিএক্স বিভাগের জন্য অধ্যায় তালিকাটি দেখুন - এটি সেখানে নেই। আর ${var##prefix_pattern}হল না আসলে ব্যাশ-নির্দিষ্ট হয়; এটি পসিএক্স শ স্ট্যান্ডার্ডে রয়েছে , বিভাগ ২.6.২ (লিঙ্কযুক্ত) এর শেষে দেখুন, সুতরাং revএটির বিপরীতে , এটি সর্বদা কোনও অনুবর্তী শেলটিতে পাওয়া যায় on
চার্লস ডাফি

89

এটি কেবল ব্যবহার করে সম্ভব নয় cut। এখানে ব্যবহারের একটি উপায় grep:

grep -o '[^,]*$'

অন্যান্য বিলিবিদের জন্য কমাটি প্রতিস্থাপন করুন।


3
বিপরীত কাজটি করতে, এবং শেষ ক্ষেত্রটি ছাড়া সমস্ত কিছুই সন্ধান করুন:grep -o '^.*,'
এরিয়েল

2
এটি বিশেষত কার্যকর ছিল, কারণ revআমার ক্ষেত্রে একটি ইস্যু মাল্টিবাইট ইউনিকোড অক্ষর যুক্ত করুন।
ব্রাইস

3
আমি মিনজিডব্লিউতে এটি করার চেষ্টা করছিলাম কিন্তু আমার গ্রেপ সংস্করণটি -o সমর্থন করে না, তাই আমি ব্যবহার করেছি sed 's/^.*,//'যা সমস্ত অক্ষরকে প্রতিস্থাপন করে এবং শেষ কমাটি খালি স্ট্রিং সহ অন্তর্ভুক্ত করে।
TamaMcGlinn

46

অজানা ছাড়া? ... তবে এটি অ্যাজকের সাথে এত সহজ:

echo 'maps.google.com' | awk -F. '{print $NF}'

আপনার পকেটে থাকার জন্য এডাব্লুকে এক উপায় আরও শক্তিশালী সরঞ্জাম। -এফ ক্ষেত্রে যদি ক্ষেত্রের বিভাজক NF হয় তবে ক্ষেত্র সংখ্যা (শেষের সূচকের জন্যও দাঁড়িয়ে আছে)


2
এটি সর্বজনীন এবং এটি প্রতিবার প্রত্যাশার মতো কাজ করে। এই cutদৃশ্যে, ওপি'র চূড়ান্ত আউটপুট অর্জন করতে ব্যবহার করা "কাটা" স্টেকের জন্য চামচ ব্যবহার করার মতো (পাং উদ্দেশ্যযুক্ত :))। awkস্টেক ছুরি।
Hickory420

3
echoলম্বা ফাইল ব্যবহারের জন্য স্ক্রিপ্টটি কমিয়ে দিতে পারে এর অপ্রয়োজনীয় ব্যবহার এড়িয়ে চলুন awk -F. '{print $NF}' <<< 'maps.google.com'
অনিল_এম

14

একাধিক উপায় আছে। আপনি এটি ব্যবহার করতে পারেন।

echo "Your string here"| tr ' ' '\n' | tail -n1
> here

স্পষ্টতই, টিআর কমান্ডের জন্য ফাঁকা স্থান ইনপুটটি আপনার প্রয়োজনীয় ডিলিমিটারের সাথে প্রতিস্থাপন করা উচিত।


ধন্যবাদ!
ব্যস্তবক্সে

1
এটি আমার কাছে সহজ উত্তর, কম পাইপ এবং আরও পরিষ্কার অর্থ বলে মনে হচ্ছে
জো বুটলার

1
এটি একটি সম্পূর্ণ ফাইলের জন্য কাজ করবে না, যা ওপি সম্ভবত বোঝাতে চেয়েছিল।
আমির

7

কাটা ছাড়া আর কিছুই ব্যবহারের একমাত্র সমাধান এটি সম্ভব:

প্রতিধ্বনি "স্ট্রিং" | কাটা-ডি '। -ফ 2- [পুনরাবৃত্তি_পথে চালানো_ পার্ট_ফরভার_আর_উন্টিল_আউট_ মেমোরি:] | কাটা-ডি '। -f2-

এই সমাধানটি ব্যবহার করে ক্ষেত্রের সংখ্যা প্রকৃতপক্ষে অজানা এবং সময়ে সময়ে হতে পারে। তবে লাইনের দৈর্ঘ্যটি নতুন লাইন চরিত্র সহ LINE_MAX অক্ষর বা ক্ষেত্রের বেশি হওয়া উচিত না, তারপরে একটি স্বেচ্ছাসেবী সংখ্যার ক্ষেত্র কখনই এই সমাধানের আসল শর্ত হিসাবে অংশ নিতে পারে না।

হ্যাঁ, একটি অত্যন্ত নির্বোধ সমাধান তবে আমি মনে করি যে মানদণ্ডগুলি পূরণ করে তার একমাত্র সমাধান।


2
খুশী হলাম। শুধু শেষ '। "স্ট্রিং" বন্ধ এবং এটি কাজ করে।
ম্যাট

2
আমি ভালবাসি যখন সবাই বলে যে কোনও কিছু অসম্ভব এবং তারপরে কেউ কোনও কাজের উত্তর দিয়ে চিমে ch এমনকি যদি এটি সত্যিই খুব নির্বোধ হয়।
বিউজর

cut -f2-আউটপুট আর পরিবর্তন না হওয়া অবধি একটি লুপে পুনরাবৃত্তি করতে পারে ।
loa_in_

4

যদি আপনার ইনপুট স্ট্রিংয়ে ফরোয়ার্ড স্ল্যাশ না থাকে তবে আপনি ব্যবহার করতে পারেন basenameএবং একটি সাবশেল:

$ basename "$(echo 'maps.google.com' | tr '.' '/')"

এই ব্যবহার করে না sedবা awkকিন্তু এটি ব্যবহার করে না cutপারেন, তাই আমি পুরোপুরি নিশ্চিত সেটি যদি ভাষায় যেমন প্রশ্নের উত্তর হিসেবে যোগ্যতা নই।

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

$ basename "$(echo 'maps.google.com/some/url/things' | tr '/' '|' | tr '.' '/')" | tr '|' '/'

2

নিম্নলিখিত একটি বন্ধুর পরামর্শ কার্যকর করে

#!/bin/bash
rcut(){

  nu="$( echo $1 | cut -d"$DELIM" -f 2-  )"
  if [ "$nu" != "$1" ]
  then
    rcut "$nu"
  else
    echo "$nu"
  fi
}

$ export DELIM=.
$ rcut a.b.c.d
d

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

0

আপনার যদি ফাইললিস্ট.টিএসটি নামের একটি ফাইল থাকে তবে এটি নীচের মতো একটি তালিকা পাথ: c: /dir1/dir2/file1.h c: /dir1/dir2/dir3/file2.h

তারপরে আপনি এটি করতে পারেন: rev filelist.txt | কাট-ডি "/" -ফ 1 | এনজিনের পার


0

এটি কেবল মজাদার জন্য এই পুরানো প্রশ্নের সাথে একটি দৃষ্টিভঙ্গি যুক্ত করা:

$ cat input.file # file containing input that needs to be processed
a;b;c;d;e
1;2;3;4;5
no delimiter here
124;adsf;15454
foo;bar;is;null;info

$ cat tmp.sh # showing off the script to do the job
#!/bin/bash
delim=';'
while read -r line; do  
    while [[ "$line" =~ "$delim" ]]; do
        line=$(cut -d"$delim" -f 2- <<<"$line")
    done
    echo "$line"
done < input.file

$ ./tmp.sh # output of above script/processed input file
e
5
no delimiter here
15454
info

বাশ ছাড়াও, কেবল কাটা ব্যবহৃত হয়। ভাল, এবং প্রতিধ্বনি, আমি অনুমান।


মেহ, কেন কেবল কাটাটি পুরোপুরি সরান না এবং কেবল বাশ ব্যবহার করুন ... x] while read -r line; do echo ${line/*;}; done <input.fileএকই ফলাফল দেয়।
কাফে মায়ার্স

-1

আমি বুঝতে পেরেছিলাম যে আমরা যদি কেবল একটি অনুমানযোগ্য ডিলিমিটারের উপস্থিতি নিশ্চিত করি তবে এটি কার্যকর হয়। সুতরাং আমার ক্ষেত্রে আমার কাছে কমা এবং সাদা জায়গার ডিলিমিটার রয়েছে। আমি শেষে একটি স্থান যুক্ত করি;

$ ans="a, b"
$ ans+=" "; echo ${ans} | tr ',' ' ' | tr -s ' ' | cut -d' ' -f2
b

এবং ans="a, b, c"উত্পাদন করে b, যা "ক্ষেত্রের সংখ্যা অজানা বা প্রতিটি লাইনের সাথে পরিবর্তিত হয়" এর প্রয়োজনীয়তা পূরণ করে না ।
jw
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.