$ @ প্রথম যুক্তি ব্যতীত


36

আমাকে একটি শেল স্ক্রিপ্ট লিখতে হবে যা এইভাবে চলে:

./myscript arg1 arg2_1 arg2_2 arg2_3 ....... arg2_#

স্ক্রিপ্টের ভিতরে একটি লুপ রয়েছে is

for i in $@

তবে, যেমনটি আমি জানি, $ @ $ 1 পর্যন্ত $ ($ # - 1) পর্যন্ত অন্তর্ভুক্ত। তবে আমার প্রোগ্রামটির জন্য $ 1 2 $ 3 $ 4 এর থেকে আলাদা আলাদা I আমি $ 2 থেকে শেষ পর্যন্ত লুপ করতে চাই ... আমি কীভাবে এটি অর্জন করব? ধন্যবাদ:)

উত্তর:


47

প্রথমত, লক্ষ্য করুন যে $@উদ্ধৃতিগুলি ব্যতীত কোনও লাভ হয় না এবং ব্যবহার করা উচিত নয়। $@কেবল উদ্ধৃত ( "$@") এবং তালিকা প্রসঙ্গে ব্যবহার করা উচিত ।

for i in "$@" একটি তালিকা প্রসঙ্গে হিসাবে যোগ্যতা অর্জন করে, তবে এখানে, অবস্থানগত পরামিতিগুলি লুপ করার জন্য, প্রচলিত, সর্বাধিক বহনযোগ্য এবং সহজ ফর্মটি হ'ল:

for i
do something with "$i"
done

এখন, দ্বিতীয়টি থেকে শুরু হওয়া উপাদানগুলি লুপ করার জন্য, প্রমিত এবং সর্বাধিক বহনযোগ্য উপায়টি হ'ল shift:

first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done

এর পরে shift, আগে যা ব্যবহৃত হত তা $1তালিকা থেকে সরানো হয়েছে (তবে আমরা এটি সংরক্ষণ করেছি $first_arg) এবং যা থাকত $2তা এখন রয়েছে $1। অবস্থানগত পরামিতিগুলি বামে অবস্থানে স্থানান্তরিত করা হয়েছে 1( shift 22 দ্বারা শিফটে ব্যবহার করুন ...)। সুতরাং মূলত, আমাদের লুপটি শেষের দ্বিতীয় আর্গুমেন্ট হিসাবে ব্যবহৃত থেকে লুপিং হয়।

সঙ্গে bash(এবং zshএবং ksh93, কিন্তু যে এটা), একটি বিকল্প করতে হয়:

for i in "${@:2}"
do something with "$i"
done

তবে নোট করুন যে এটি স্ট্যান্ডার্ড shসিনট্যাক্স নয় তাই শুরু হওয়া কোনও স্ক্রিপ্টে ব্যবহার করা উচিত নয় #! /bin/sh -

ইন zshবা yash, এছাড়াও আপনি করতে পারেন:

for i in "${@[3,-3]}"
do something with "$i"
done

3 য় থেকে 3 য় শেষ আর্গুমেন্টে লুপ করতে।

ইন zsh, $@এছাড়াও $argvঅ্যারে হিসাবে পরিচিত । সুতরাং অ্যারেগুলির শুরু বা শেষ থেকে উপাদানগুলিকে পপ করতে, আপনি এটিও করতে পারেন:

argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()

( shiftএছাড়াও লেখা যেতে পারে 1=()মধ্যে zsh)

ইন bash, আপনি কেবল বিল্টিন $@সহ উপাদানগুলিকে বরাদ্দ করতে পারেন set, তাই 3 এলিমেন্টটি শেষ থেকে পপ করতে, এটি এমন কিছু হবে:

set -- "${@:1:$#-3}"

এবং 3 য় থেকে 3 য় শেষ পর্যন্ত লুপ করতে:

for i in "${@:3:$#-5}"
do something with "$i"
done

POSIXly, এর সর্বশেষ 3 টি উপাদান পপ করতে "$@"আপনাকে একটি লুপ ব্যবহার করতে হবে:

n=$(($# - 3))
for arg do
  [ "$n" -gt 0 ] && set -- "$@" "$arg"
  shift
  n=$((n - 1))
done

2
একটি বিকল্প (এবং for ((i=2; i<=$#; i++)); do something with "${!i}"; done
কুরুচিপূর্ণ

আমি এই সংস্করণটির সাথে আরও বেশি পরিচিত, যেহেতু আমি সি ++ :) এর সাথে আরও বেশি পরিচিত
ইউজার 40780

10

আমি মনে করি আপনি shiftবিল্টিন চান । এটি নাম পরিবর্তন করে$2 করতে $1, $3করতে $2, ইত্যাদি

এটার মত:

shift
for i in "$@"; do
    echo $i
done

আপনি কি আরও বিস্তারিতভাবে ব্যাখ্যা করতে পারেন যে আমি লুপের জন্য কীভাবে এটি অর্জন করব? ধন্যবাদ.
ব্যবহারকারী 40780

1
আপনি করবেন না - আপনি forলুপটি প্রবেশের আগে এটি ব্যবহার করেন , তারপরে আপনি সাধারণত $ @ এর মধ্য দিয়ে লুপ করেন। shiftকল করার পরে , $ @ হওয়া উচিতarg2_1 arg2_2 arg2_3...
জন

তবে, আমার আরও একটি প্রশ্ন থাকবে: ধরুন আমি $ 1 থেকে $ ($ # - 2) পর্যন্ত লুপ করতে চাই (অর্থাত্ arg_1 পর্যন্ত arg_2 _ # - 1, আরগ_2 _ # বাদে) ... আমার কী করা উচিত?
ব্যবহারকারী 40780

2

গুহামানদের দৃষ্টিভঙ্গি সবসময় থাকে:

first=1
for i
do
        if [ "$first" ]
        then
                first=
                continue
        fi
        something with "$i"
done

এটি $@অক্ষত থাকে (আপনি যদি এটি পরে ব্যবহার করতে চান) এবং প্রতিটি যুক্তিটি কেবল লুপ করে তবে প্রথমটি প্রক্রিয়া করে না।


1

ব্যাশে আপনি সেই লুপটি সুস্পষ্ট সূচী দিয়েও লিখতে পারেন:

for ((i=2; i<=$#; ++i)); do
  process "${!i}"
done

এটি দ্বিতীয় থেকে শেষ পর্যন্ত সমস্ত যুক্তির উপরে পুনরাবৃত্তি করে। পরিবর্তে আপনি যদি সর্বশেষ যুক্তিটি বাদ দিতে চান তবে কেবল এটি তৈরি করুন

for ((i=1; i<=$#-1; ++i)); do
  process "${!i}"
done

এবং আপনি যদি কেবলমাত্র প্রতিটি অন্যান্য যুক্তি নিতে চান তবে এটি লিখুন

for ((i=1; i<=$#; i+=2)); do
  process "${!i}"
done

এর পেছনের গল্পটি হ'ল বিল্টিনের গাণিতিক সংস্করণ, যুক্তি-গণনা এবং ভেরিয়েবল forইন্ডায়ারেশনের সাথে মিলিত$#${…}

একটি দুর্দান্ত অ্যাপ্লিকেশন হ'ল আপনি এটি লুপের অভ্যন্তরে সিদ্ধান্ত নিতে ব্যবহার করতে পারেন, কোনও প্রদত্ত বিকল্পটি যুক্তিটি গ্রহণ করবে কিনা যা এটি মান হিসাবে অনুসরণ করে। যদি এটি হয়, পরবর্তী মূল্য গ্রহণ এবং পুনরাবৃত্তির সময় এড়াতে ইনক্রিমেন্ট i(যেমন লিখন : $((++i)))।

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