একটি কমান্ডের আর্গুমেন্টে একটি অ্যারে রূপান্তর?


39

আমার কাছে একটি কমান্ডের "বিকল্পগুলি" এর অ্যারে রয়েছে।

my_array=(option1 option2 option3)

অ্যারে থেকে মানগুলি বিকল্প হিসাবে ব্যবহার করে আমি এই কমান্ডটিকে বাশ স্ক্রিপ্টে কল করতে চাই। সুতরাং, command $(some magic here with my_array) "$1"হয়ে:

command -option1 -option2 -option3 "$1"

আমি এটা কিভাবে করবো? এটা কি সম্ভব?


1
সুতরাং আপনি -প্রতিটি শব্দের শুরুতে যুক্ত করতে চান my_array?
কেভিন

@ কেভিন: হ্যাঁ, এবং এটি কার্যকর করুন। সমস্ত লাইন একই বাশ স্ক্রিপ্টের অভ্যন্তরে। আমি এটি জিজ্ঞাসা করছি কারণ এই একই অপশনগুলি স্ক্রিপ্টের অভ্যন্তরে প্রচুর জায়গায় ব্যবহৃত হতে চলেছে, সুতরাং তাদের চারপাশের সমস্ত অনুলিপি না করে আমি একটি অ্যারের সম্পর্কে ভাবলাম।
এখনও কেউ আপনাকে এমএস-ডস

1
এটি অর্থহীন বলে মনে হতে পারে তবে আপনি যদি বড় শেল স্ক্রিপ্ট তৈরি করেন তবে আপনার পার্লটি দেখতে হবে, এই ধরণের জিনিসটি সেখানে করা খুব সহজ।
আলফা 64

উত্তর:


43

আমি একটি সহজ bashউপায় পছন্দ করব :

command "${my_array[@]/#/-}" "$1"

এর এক কারণ হ'ল ফাঁকা স্থান। উদাহরণস্বরূপ:

my_array=(option1 'option2 with space' option3)

sedভিত্তিক সমাধান এটা রূপান্তরিত হবে -option1 -option2 -with -space -option3(দৈর্ঘ্য 5), কিন্তু উপরে bashসম্প্রসারণ সেটিকে রূপান্তরিত হবে -option1 -option2 with space -option3(দৈর্ঘ্য এখনও 3)। কদাচিৎ, তবে কখনও কখনও এটি গুরুত্বপূর্ণ, উদাহরণস্বরূপ:

bash-4.2$ my_array=('Ffoo bar' 'vOFS=fiz baz')
bash-4.2$ echo 'one foo bar two foo bar three foo bar four' | awk "${my_array[@]/#/-}" '{print$2,$3}'
 two fiz baz three

যদি আমি সঠিকভাবে বুঝতে পারি, এই পরিবর্তনশীল প্রতিস্থাপনটি কোনও ফাংশনে আবৃত করা যায় না, বা কোনও ভেরিয়েবলের জন্য বরাদ্দ করা যায় না, তাই না? এটি সরাসরি কমান্ড অনুরোধে যেতে হবে।
কনরাড রুডলফ

1
@KonradRudolph, আপনি দীর্ঘ হিসাবে অন্যান্য পরিবর্তনশীল তা ধার্য করতে পারেন হিসাবে আপনি অ্যারে নিয়োগ যেমন একটি করুন: somevar=("${my_array[@]/#/-}")(উল্লেখ্য মান প্রায় প্রথম বন্ধনী।) তারপর অবশ্যই আপনি অ্যারে যেমন হ্যান্ডলিং যখন এটি ব্যবহার করা চালিয়ে যেতে হবে: echo "${somevar[@]}"। কার্যাদি সম্পর্কে, আপনি ভাষা সম্ভাবনার দ্বারা খুব সীমিত। : আপনি একটি অ্যারের পাস করতে পারেন somefunc "${my_array[@]/#/-}"ভিতরে আপনি এটা থাকবে তারপর, $@: function somefunc() { echo "$@"; }। তবে একই $@সাথে অন্যান্য প্যারামিটারগুলিও উপস্থিত থাকবে, যদি উপস্থিত থাকে এবং স্টডআউট ব্যতীত পরিবর্তিত অ্যারেটি ফেরানোর কোনও উপায় নেই।
manatwork

যথেষ্ট অদ্ভুত, zsh এর সাথে কাজ করে না। আমি প্রথমবার এমন কোনও কিছুর হোঁচট খেয়েছিলাম যা ব্যাশে কাজ করে তবে zsh নয়।
হাই-অ্যাঞ্জেল

@ হাই-অ্যাঞ্জেল, আপনি কি নিশ্চিত @অ্যারে সাবস্ক্রিপ্ট হিসাবে ব্যবহার করেছেন? আমি এটিকে zsh 5.5.1 দিয়ে একটি পরীক্ষা দিয়েছি এবং কেবলমাত্র তফাতটি আমি লক্ষ্য করেছি যে zsh কেবল প্রতিটি আইটেমকে প্রিফিক্স করে যখন লেখা হয় ${my_array[@]/#/-}, যখন ব্যাশ *সাবস্ক্রিপ্টের জন্যও এটি করেছিল।
manatwork

ওহ, দুঃখিত, আমি কিছু ভুল হতে পারে, সত্যিই আমার জন্য কাজ করে!
হাই-এঞ্জেল

2

আমি প্রক্রিয়া করিনি যে এটি একটি অ্যারেতে ছিল এবং একটি স্ট্রিংয়ের মধ্যে সাদা স্থানকে পৃথক করে নিয়ে ভাবছিলাম। এই সমাধানটি এটির সাথে কাজ করবে, তবে এটি অ্যারে হিসাবে দেওয়া হবে, ম্যান্যাটওয়ার্কের সমাধান ( @{my_array[@]/#/-}) সহ যান।


এটি sedএবং একটি সাব-শেলের সাথে খুব খারাপ নয় । রেজেক্স কতটা সহজ তা নির্ভর করে আপনি বিকল্পগুলি সম্পর্কে কী গ্যারান্টি দিতে পারেন তার উপর depends বিকল্পগুলি যদি সমস্ত একটি "শব্দ" ( a-zA-Z0-9কেবল) হয় তবে একটি সাধারণ শুরুর শব্দ সীমানা ( \<) যথেষ্ট হবে:

command $(echo $my_array | sed 's/\</-/g') "$1"

যদি আপনার বিকল্পগুলির অন্যান্য অক্ষর থাকে (সম্ভবত -) তবে আপনার কিছুটা জটিল জটিল প্রয়োজন:

command $(echo $my_array | sed 's/\(^\|[ \t]\)\</\1-/g') "$1"

^লাইনের প্রারম্ভের সাথে [ \t]মেলে, একটি স্থান বা ট্যাবের সাথে \|মেলে, উভয় পক্ষের ( ^বা [ \t]), \( \)গ্রুপগুলির (এর জন্য \|) \<মেলে এবং ফলাফলটি সংরক্ষণ করে, একটি শব্দের শুরুতে মেলে matches \1প্রথম ম্যাচটি পেরেন ( \(\)) থেকে রেখে প্রতিস্থাপন শুরু করে এবং -অবশ্যই আমাদের প্রয়োজনীয় ড্যাশ যুক্ত করে।

এইগুলি gnu সেডের সাথে কাজ করে, যদি তারা আপনার সাথে কাজ না করে তবে আমাকে জানান।

এবং আপনি যদি একই জিনিসটি একাধিকবার ব্যবহার করেন তবে আপনি একবার এটি গণনা করতে এবং সঞ্চয় করতে পারেন:

opts="$(echo $my_array | sed 's/\(^\|[ \t]\)\</\1-/g')"
...
command $opts "$1"
command $opts "$2"

এটি ম্যাক ওএস এক্স সেডের সাথে কাজ করে না, তাই আমার ব্যবহারের প্রয়োজন ছিল gsed(আমি ব্যবহার করে ইনস্টল করেছি homebrew)। আরেকটি জিনিস: পরিবর্তে echo $my_array, echo ${my_array[@]}সমস্ত আইটেম থেকে আমাকে পেতে প্রয়োজন my_array: echo $my_arrayআমাকে কেবল প্রথম উপাদানটিই দিয়েছিল। তবে রেগেক্সের উত্তর এবং ব্যাখ্যার জন্য ধন্যবাদ, বিশেষত "শব্দ সীমানা" সম্পর্কে, এটি অত্যন্ত কার্যকর। :)
এখনও কেউ আপনাকে এমএস-ডস

আমি যদি স্ক্রিপ্টটি এই শব্দ সীমানা বৈশিষ্ট্যের সাথে সামঞ্জস্য না করে তবে স্ক্রিপ্ট থেকে প্রস্থান করতে চাই। আমি এটা কিভাবে করব? সেড সংস্করণ মুদ্রণ এবং এটি তুলনা? সেডের কোন সংস্করণ থেকে এই বৈশিষ্ট্যটি যুক্ত করা হয়েছিল?
এখনও কেউ আপনাকে এমএস-ডস

1
@ SomebodystillusesyouMS-DOS এর আমার প্রথম চিন্তা সরাসরি কিনা এটি কাজ করে চেক করতে হয় - [ $(echo x | sed 's/\</y/') == "yx" ] || exit
কেভিন

2
অ্যারে উপাদানগুলির মধ্যে কোনওটিতে বিশেষ অক্ষর রয়েছে, এটি স্পষ্টত এবং অনিচ্ছাকৃতভাবে সাদা স্পেসে ভাঙ্গবে।
গিলস 'দুষ্ট হওয়া বন্ধ করুন'

1
@ সোমবোডিস্টিলুসিউইউএমএস-ডস গিলস ঠিক আছে, আপনার নিজের গ্রহণের ব্যবস্থাটি পরিবর্তন করা উচিত।
কেভিন

0
[srikanth@myhost ~]$ sh sample.sh 

-option1 -option2 -option3

[srikanth@myhost ~]$ cat sample.sh

#!/bin/bash

my_array=(option1 option2 option3)

echo ${my_array[@]} | sed 's/\</-/g'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.