কীভাবে একটি ডিলিমিটেড স্ট্রিংকে এজেকে বিভক্ত করবেন?


169

এটিতে পাইপের চিহ্ন থাকা অবস্থায় স্ট্রিংটি কীভাবে বিভক্ত করা যায় |। আমি তাদের অ্যারে হতে বিভক্ত করতে চান।

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

echo "12:23:11" | awk '{split($0,a,":"); print a[3] a[2] a[1]}'

যা ভাল কাজ করে। যদি আমার স্ট্রিংটি এর মতো হয় "12|23|11"তবে আমি কীভাবে এগুলিকে একটি অ্যারেতে ভাগ করব?


3
নোট করুন যে আপনার আউটপুট বিন্যাস ছাড়াই অ্যারে উপাদানগুলিকে যুক্ত করছে conc আপনি যদি পরিবর্তে তাদের আলাদা করতে চান তবে তাদের OFSমধ্যে printপৃথক যুক্তি হিসাবে দেখিয়ে কমা করুন stick
dubiousjim

অথবা আপনি echo "12:23:11" | sed "s/.*://"
সেড

@ স্লুশি: আপনার আদেশটি প্রশ্নকারীকে যা প্রয়োজন তা মোটেই নয়। আপনার কমান্ড ( echo "12:23:11" | sed "s/.*://") সর্বশেষ ":" অবধি সমস্ত কিছু মুছে ফেলবে (এবং অন্তর্ভুক্ত) কেবল "11" রেখে ... এটি সর্বশেষ সংখ্যা পাওয়ার জন্য কাজ করে, তবে পাওয়ার জন্য পরিবর্তন করতে হবে (পড়ার পথে কোনও অসুবিধাতে) ২ য় নম্বর ইত্যাদি, অ্যাজক (এবং অ্যাডকের বিভক্ত) অনেক বেশি মার্জিত এবং পঠনযোগ্য।
অলিভিয়ার ডুলাক

আপনার যদি কোনও একক চরিত্রের বিভাজন দরকার হয় তবে আপনি ব্যবহার করতে পারেনcut
সিসিপিজ্জা

উত্তর:


274

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

echo "12|23|11" | awk '{split($0,a,"|"); print a[3],a[2],a[1]}'

2
@ মোহাম্মদ স্যালিগ, আপনি যদি সোলারিতে থাকেন তবে আপনার স্ট্রিংয়ের দৈর্ঘ্য অনুসারে / usr / xpg4 / bin / awk ব্যবহার করতে হবে ।
দিমিত্রে রাদৌলভ

5
'আমার পক্ষে কাজ করছে না'। বিশেষত প্রতিধ্বনিত মানগুলির মধ্যে কলোন এবং '|' তে বিভক্ত হওয়ার জন্য বিভক্ত সেট ??? ভুল টাইপ করেছেন? সবার জন্য শুভ কামনা.
শেল্টার

1
কিছু সিনট্যাক্স ব্যাখ্যা দিয়ে ভাল।
অ্যালস্টন

2
এটি GNU awk এ কাজ করবে না, কারণ তৃতীয় যুক্তি splitহ'ল নিয়মিত প্রকাশ, এবং |এটি একটি বিশেষ প্রতীক, যা এড়াতে হবে। ব্যবহার করুনsplit($0, a, "\|")
হোয়াইটওয়াইন্ড

1
@ হোয়াইটওয়াইন্ড: "নিশ্চিত করার" অন্য একটি উপায় যা |চর হিসাবে দেখা হয় এবং বিশেষ চিহ্ন হিসাবে দেখা যায় না []: এটি হল split($0, a, "[|]") # ' ie |' এর চেয়ে ভাল আমি পছন্দ করি, কিছু ক্ষেত্রে, বিশেষত কিছুটা রেজিপএক্সের রূপ হিসাবে ( পার্ল বনাম গ্রেপ বনাম .. অন্যরা?) "" "থাকতে পারে অক্ষরে অক্ষরে বর্ণিত এবং "\ |" বিপরীতে পরিবর্তে রেজেক্স বিভাজক হিসাবে দেখা ... ymmv
অলিভিয়ার ডুলাক

119

একটি অ্যারেতে একটি স্ট্রিং বিভক্ত করতে awkআমরা ফাংশনটি ব্যবহার করি split():

 awk '{split($0, a, ":")}'
 #           ^^  ^  ^^^
 #            |  |   |
 #       string  |   delimiter
 #               |
 #               array to store the pieces

যদি কোনও বিভাজক দেওয়া না FSহয় তবে এটি স্পেসটি ডিফল্ট করে এটি ব্যবহার করে :

$ awk '{split($0, a); print a[2]}' <<< "a:b c:d e"
c:d

আমরা একটি বিভাজক দিতে পারি, উদাহরণস্বরূপ ::

$ awk '{split($0, a, ":"); print a[2]}' <<< "a:b c:d e"
b c

যা এর মাধ্যমে সেট করার সমতুল্য FS:

$ awk -F: '{split($0, a); print a[1]}' <<< "a:b c:d e"
b c

গোকের মধ্যে আপনি পৃথককে একটি রেজিপ্সপ হিসাবে সরবরাহ করতে পারেন:

$ awk '{split($0, a, ":*"); print a[2]}' <<< "a:::b c::d e" #note multiple :
b c

এমনকি চতুর্থ প্যারামিটার ব্যবহার করে প্রতিটি পদক্ষেপে ডিলিমিটার কী ছিল তা দেখুন:

$ awk '{split($0, a, ":*", sep); print a[2]; print sep[1]}' <<< "a:::b c::d e"
b c
:::

আসুন জিএনইউ অ্যাজকের ম্যান পেজটি উদ্ধৃত করুন :

বিভক্ত (স্ট্রিং, অ্যারে [, ফিল্ডস্যাপ [, seps]])

ডিভাইড স্ট্রিং টুকরা দ্বারা পৃথক fieldsep এবং টুকরা সঞ্চয় অ্যারে এবং বিভাজক স্ট্রিং seps অ্যারে। প্রথম টুকরা সংরক্ষণ করা হয় array[1], দ্বিতীয় টুকরা মধ্যে array[2], এবং আরও। তৃতীয় আর্গুমেন্ট, ফিল্ডস্যাপের স্ট্রিং মান হ'ল একটি রেজিপ্যাক্স যেখানে কোথায় স্ট্রিং বিভক্ত হবে তা বর্ণনা করে ( এফএস যতটা ইনপুট রেকর্ডগুলি কোথায় বিভক্ত করতে হবে তা বর্ণনা করে এমন একটি রেজিএক্সপ্যাক হতে পারে)। যদি ফিল্ডস্যাপ বাদ দেওয়া হয়, তবে FS এর মান ব্যবহার করা হয়। split()তৈরি উপাদানগুলির সংখ্যা প্রদান করে। সেপস হল একটি gawkএক্সটেনশন, এর seps[i]মধ্যে বিভাজক স্ট্রিং রয়েছেarray[i]এবং array[i+1]। যদি ফিল্ডস্যাপটি একটি একক স্থান হয় তবে যে কোনও শীর্ষস্থানীয় শ্বেতস্পেস প্রবেশ করে seps[0]এবং যে কোনও পূর্ববর্তী সাদা স্থান , ুকে যায় seps[n], সেখানে n এর ফেরত মান হয় split()(অর্থাত্ অ্যারেতে উপাদানের সংখ্যা)।


কেবল উল্লেখ করুন যে আপনি gnu awk ব্যবহার করছেন, নিয়মিত awk নয় (যা সেপসে বিভাজক সংরক্ষণ করে না [] এবং অন্যান্য সীমাবদ্ধতা রয়েছে)
অলিভিয়ার ডুলাক ২

17

আরও নির্দিষ্ট হতে দয়া করে! "এটি কাজ করে না" বলতে কী বোঝ? নির্ভুল আউটপুট (বা ত্রুটি বার্তা), আপনার ওএস এবং অ্যাডওয়ান সংস্করণ পোস্ট করুন:

% awk -F\| '{
  for (i = 0; ++i <= NF;)
    print i, $i
  }' <<<'12|23|11'
1 12
2 23
3 11

অথবা, বিভাজন ব্যবহার করে:

% awk '{
  n = split($0, t, "|")
  for (i = 0; ++i <= n;)
    print i, t[i]
  }' <<<'12|23|11'
1 12
2 23
3 11

সম্পাদনা: উপর সোলারিস আপনি ব্যবহার করতে হবে POSIX awk ( , / usr / xpg4 / বিন / awk 4000 ক্ষেত্র সঠিকভাবে প্রক্রিয়া করার জন্য)।


for(i = 0বা for(i = 1?
পাইট্রনিক্স

i = 0, কারণ আমি পরে ++ i ব্যবহার করি (আমি ++ নয়)।
দিমিত্রে রাদৌলভ

3
ঠিক আছে - আমি এটি লক্ষ্য করিনি। আমি for (i = 1; i <= n; ++i)
দৃ strongly়ভাবে

5

echo "..." | awk ...সমাধানটি অপ্রয়োজনীয় forkএবং execসিস্টেম কল হিসাবে কল করা পছন্দ করি না ।

আমি একটু মোচড় দিয়ে একটি ডিমিট্রের সমাধানটি পছন্দ করি

awk -F\| '{print $3 $2 $1}' <<<'12|23|11'

বা কিছুটা সংক্ষিপ্ত সংস্করণ:

awk -F\| '$0=$3 $2 $1' <<<'12|23|11'

এই ক্ষেত্রে আউটপুট রেকর্ড একসাথে রাখা যা সত্য শর্ত, তাই এটি মুদ্রিত হয়।

এই নির্দিষ্ট ক্ষেত্রে stdinপুনর্নির্দেশটি একটি সেট করে বাঁচা যায় অভ্যন্তরীণ পরিবর্তনশীল:

awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}'

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

T='12|23|11';echo -n ${T##*|};T=${T%|*};echo ${T#*|}${T%|*}
T='12|23|11';echo ${T:6}${T:3:2}${T:0:2}

সব ক্ষেত্রে ফলাফল হয়

112312

আমি মনে করি শেষ ফলাফলটি অ্যাডক অ্যারে ভেরিয়েবল উল্লেখ হিসাবে বিবেচিত হয়েছিল, মুদ্রণ আউটপুট উদাহরণটি নির্বিশেষে প্রদত্ত। তবে আপনি আপনার শেষ ফলাফলটি সরবরাহ করতে সত্যিই খুব সহজ বাশ কেস মিস করেছেন। টি = '12: 23: 11 '; প্রতিধ্বনি $ {টি //:}
ড্যানিয়েল লিস্টন

@ ড্যানিয়েললিস্টন আপনি ঠিক বলেছেন! ধন্যবাদ! আমি জানতাম না যে এই bashমত প্রকাশের পিছনে / ছেড়ে যেতে পারে ...
সত্য

4

আসলে awk'ইনপুট ফিল্ড বিভাজক পরিবর্তনশীল' লিঙ্ক নামে একটি বৈশিষ্ট্য রয়েছে । এটি এইভাবে ব্যবহার করা যায়। এটি আসলে কোনও অ্যারে নয়, তবে এটি অভ্যন্তরীণ $ ভেরিয়েবলগুলি ব্যবহার করে। একটি সাধারণ স্ট্রিং বিভক্ত করার জন্য এটি আরও সহজ।

echo "12|23|11" | awk 'BEGIN {FS="|";} { print $1, $2, $3 }'

3
echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

কাজ করা উচিত.



1

ঠাট্টা? :)

কেমন echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

এটি আমার আউটপুট:

p2> echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'
112312

সুতরাং আমি অনুমান করি যে এটি সর্বোপরি কাজ করছে ..


স্ট্রিং দৈর্ঘ্যের কারণে? যেহেতু, আমার স্ট্রিংয়ের দৈর্ঘ্য 4000
any

1

আমি জানি এটি এক ধরণের পুরানো প্রশ্ন, তবে আমি ভেবেছিলাম আমার কৌশলটি কেউ পছন্দ করবে। বিশেষত যেহেতু এই দ্রষ্টব্য নির্দিষ্ট আইটেমের মধ্যে সীমাবদ্ধ নয়।

# Convert to an array
_ITEMS=($(echo "12|23|11" | tr '|' '\n'))

# Output array items
for _ITEM in "${_ITEMS[@]}"; do
  echo "Item: ${_ITEM}"
done

আউটপুটটি হবে:

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