প্রথমটি বাদ দিয়ে সমস্ত যুক্তি প্রক্রিয়া করুন (ব্যাশ স্ক্রিপ্টে)


444

আমার একটি সরল স্ক্রিপ্ট রয়েছে যেখানে প্রথম যুক্তিটি ফাইল নামের জন্য সংরক্ষিত আছে এবং অন্যান্য সমস্ত alচ্ছিক যুক্তিগুলি স্ক্রিপ্টের অন্যান্য অংশে প্রেরণ করা উচিত।

গুগল ব্যবহার করে আমি এই উইকিটি পেয়েছি , তবে এটি একটি আক্ষরিক উদাহরণ দিয়েছে:

echo "${@: -1}"

আমি কাজের মতো অন্য কিছু পেতে পারি না:

echo "${@:2}"

অথবা

echo "${@:2,1}"

আমি টার্মিনাল থেকে "খারাপ প্রতিস্থাপন" পাই।

সমস্যাটি কী, এবং প্রথম আর্গুমেন্টটি বাশ স্ক্রিপ্টে পাস করা ছাড়া আমি কীভাবে সমস্ত প্রক্রিয়া করতে পারি?


21
অন্য কাউকে বিভ্রান্ত করার আহ্বান জানাতে, ভুল শেবাংটি "{@:2}"কাজ না করার কারণে সরবরাহ করা হয়েছিল , এ কারণেই উপরে সঠিক উত্তর মেলে।
গুভান্তে

3
আপনি সবেমাত্র ডিফল্ট শেল ব্যবহার করেছেন যা উবুন্টু এবং অন্যান্য অনেক লিনাক্সে ড্যাশ। ড্যাশে "$ {@: -1}" এর অর্থ: {প্যারামিটার:-শব্দ word - ডিফল্ট মানগুলি ব্যবহার করুন এবং পরামিতিটি সংজ্ঞায়িত বা শূন্য না হলে শব্দটি ব্যবহার করুন। সুতরাং ড্যাশ "$ {@: -1।" ফলাফলগুলিতে "$ @" এর মতোই ফলাফল। বাশ ব্যবহার করতে স্ক্রিপ্ট ফাইলে নিম্নোক্ত প্রথম লাইনটি ব্যবহার করুন: #! / বিন / ব্যাশ
লুয়ার্ট

উত্তর:


660

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

echo "${@:2}"

নিম্নলিখিত বাক্য গঠন:

echo "${*:2}"

পাশাপাশি কাজ করবে, তবে প্রস্তাবিত নয়, কারণ @ গর্ডন যেমন ইতিমধ্যে ব্যাখ্যা করেছেন যে এটি ব্যবহার করে *এটি সমস্ত আর্গুমেন্টকে একক যুক্তি হিসাবে ফাঁকা জায়গায় চালায়, যখন @তাদের মধ্যে বিচ্ছেদগুলি সংরক্ষণ করে (এমনকি কিছু আর্গুমেন্ট নিজেই ফাঁকা থাকে এমনকি) )। এটির সাথে পার্থক্য আসে না echo, তবে এটি অন্যান্য অনেক কমান্ডের জন্য গুরুত্বপূর্ণ।


7
আমি কেবল বুঝতে পেরেছিলাম আমার শেবাং খারাপ ছিল: #!/usr/bin/env shএজন্য আমার সমস্যা ছিল। আপনার উদাহরণটি ঠিক মত কাজ করে, উপরের সরবরাহ মতো, আমি সেই শেবাং সরিয়ে নেওয়ার পরে
থিয়েটা

110
"${@:2}"পরিবর্তে ব্যবহার করুন - ব্যবহার করে *সমস্ত আর্গুমেন্ট একসাথে ফাঁকা জায়গাগুলির সাথে একক যুক্তি হিসাবে চালিত হয়, যখন @তাদের মধ্যে বিরতিগুলি সংরক্ষণ করে (এমনকি কিছু আর্গুমেন্টে নিজেরাই ফাঁকা স্থান থাকে)। পার্থক্যটি লক্ষণীয় নয় echo, তবে এটি অন্যান্য অনেক বিষয়ের জন্য গুরুত্বপূর্ণ।
গর্ডন ডেভিসন

2
@ গর্ডন ডেভিসন এখানে পুরো বিষয়টি হ'ল যুক্তিগুলি একসাথে চালানো। আমরা যদি ফাইলের নামগুলি পাস করছিলাম তবে আপনি সঠিক হবেন। echoআপনার জন্য তাদেরকে বোঝাতে যথেষ্ট ক্ষমাশীল; অন্যান্য কমান্ডগুলি এত সুন্দর নাও হতে পারে। কেবল একটি বা অন্যটি ব্যবহার করবেন না: *এবং @এবং কখন ব্যবহার করতে হবে তার মধ্যে পার্থক্য শিখুন । আপনার তাদের সমানভাবে ব্যবহার করা উচিত। এটি কখন সমস্যা হবে তার একটি ভাল উদাহরণ: যদি $3কোনও লাইন ব্রেক ( \n) থাকে তবে এটি একটি স্থান দিয়ে প্রতিস্থাপন করা হবে, যদি আপনার ডিফল্ট $IFSভেরিয়েবল থাকে।
জেনেক্সার

1
@ জেনেক্সার: যেহেতু আমি এটি বুঝতে পেরেছি, প্রশ্নটি কীভাবে "স্ক্রিপ্টের অন্য অংশে" প্রথম যুক্তি ছাড়া কীভাবে পাস করতে হবে, echoউদাহরণ হিসাবে ব্যবহৃত হয়েছে - এই ক্ষেত্রে তাদের একসাথে চালানো উচিত নয় । আমার অভিজ্ঞতায় আপনি যে পরিস্থিতিগুলি একসাথে চালাতে চান সেগুলি বিরল ( এক উদাহরণের জন্য এই প্রশ্নটি দেখুন ) এবং "$@"আপনি যা চান তা প্রায় সর্বদা is এছাড়াও, লাইন ব্রেক নিয়ে আপনি যে সমস্যাটি উল্লেখ করেছেন তা কেবল তখনই ঘটে যখন $@(বা $*) ডাবল-কোট না থাকে।
গর্ডন ডেভিসন

@ গর্ডন ডেভিসন হুম ... আপনি ঠিক বলেছেন, এখন যে আমি এটি সম্পর্কে চিন্তা করি; লাইন বিরতি একটি সমস্যা হওয়া উচিত নয়। আমি নিশ্চয়ই অন্য কিছু ভাবছিলাম। তবে এগুলি একসাথে চালানোর বিষয়ে আমার এখনও একমত হতে হবে না; $*আমার স্ক্রিপ্টগুলিতে আমাকে প্রায়শই ব্যবহার করা প্রয়োজন ।
জেনেক্সার

180

আপনি যদি এমন কোনও সমাধান চান যা /bin/shচেষ্টা করেও কাজ করে

first_arg="$1"
shift
echo First argument: "$first_arg"
echo Remaining arguments: "$@"

shift [n]অবস্থানগত পরামিতিগুলি n বার পরিবর্তন করে । একটি shiftসেট মান $1মূল্য $2, মান $2মূল্য $3, ইত্যাদি, এর মান কমে $#এক করে।


25
+1: আপনার সম্ভবত $ 1 এ পরিবর্তন থেকে সরিয়ে নেওয়ার আগে একটি পরিবর্তনশীল হিসাবে সংরক্ষণ করা উচিত।
গ্লেন জ্যাকম্যান

3
আশ্চর্যজনকভাবে foo=shiftআমি যা আশা করি তা করে না।
কিথ স্মাইল

আমি জানি এটি পুরানো, তবে চেষ্টা করুনfoo=$(shift)
রাউমান কিদওয়াই

12
@ ইরামানকিদওয়াই এটি 2 কারণে কাজ করে না: 1) shift(শেলের মধ্যে) কোনও আউটপুট নেই। এটি কেবল ছাড়িয়ে যায় $1এবং সবকিছুকে সরিয়ে দেয়। 2) $(...)একটি সাবশেল শুরু হয়, যার নিজস্ব স্থানীয় যুক্তি রয়েছে। এটি সাবশেলে যুক্তিগুলি স্থানান্তরিত করে, যা পিতামাতাকে প্রভাবিত করে না
বেন জ্যাকসন

ধন্যবাদ :) somecommand "$1" "${@:2}"যদিও এই পদ্ধতিটি (যেমন শিফট "ইনলাইন") দিয়ে কী করার কোনও উপায় আছে ?
বেনামে


0

এটি অন্য কিছু খুঁজছেন জুড়ে এসেছিল। পোস্টটি বেশ পুরানো দেখায়, ব্যাশের সবচেয়ে সহজ সমাধানটি নীচে চিত্রিত করা হয়েছে (কমপক্ষে ব্যাশ 4) set -- "${@:#}"যেখানে আমরা যে অ্যারে এলিমেন্টকে এগিয়ে রাখতে চাই তার প্রাথমিক সংখ্যাটি এখানে ব্যবহার করে:

    #!/bin/bash

    someVar="${1}"
    someOtherVar="${2}"
    set -- "${@:3}"
    input=${@}

    [[ "${input[*],,}" == *"someword"* ]] && someNewVar="trigger"

    echo -e "${someVar}\n${someOtherVar}\n${someNewVar}\n\n${@}"

মূলত, set -- "${@:3}"পার্ল শিফটের মতো অ্যারেতে প্রথম দুটি উপাদান সরিয়ে দেয় এবং তৃতীয় সহ সমস্ত অবশিষ্ট উপাদান সংরক্ষণ করে। আমি সন্দেহ করি যে শেষ উপাদানগুলিও পপ করার উপায় আছে।

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