ব্যাচ ফাইল - কমান্ড লাইন আর্গুমেন্ট সংখ্যা


100

কিছু শেল স্ক্রিপ্টগুলি কেবল ব্যাচ ফাইলে রূপান্তর করা এবং এমন একটি জিনিস রয়েছে যা আমি খুঁজে পাচ্ছি না ... এবং এটি হ'ল কমান্ড লাইন আর্গুমেন্টের সংখ্যার একটি সহজ গণনা।

যেমন যদি তোমার থাকে:

myapp foo bar

আবরণের ভেতরে:

  • $ # -> 2
  • $ * -> ফু বার
  • $ 0 -> মায়াপ
  • $ 1 -> ফু
  • $ 2 -> বার

ব্যাচে

  • ?? -> 2 <---- কি আদেশ ?!
  • % * -> ফু বার
  • % 0 -> মায়াপ
  • % 1 -> ফু
  • % 2 -> বার

সুতরাং আমি চারপাশে তাকিয়েছি, এবং হয় আমি ভুল জায়গায় খুঁজছি বা আমি অন্ধ, তবে কমান্ড লাইন যুক্তিগুলির সংখ্যা গণনা করার উপায় খুঁজে পাচ্ছি না।

ব্যাচ ফাইলগুলির জন্য শেলের "$ #" এর মতো কোনও আদেশ আছে কি?

পুনশ্চ. আমি যে নিকটতম সন্ধান পেয়েছি তা হ'ল% 1 এর মাধ্যমে পুনরাবৃত্তি করা এবং 'শিফট' ব্যবহার করা, তবে আমাকে স্ক্রিপ্টে পরে% 1,% 2 ইত্যাদি উল্লেখ করতে হবে যাতে এটি কোনও ভাল নয়।


আপনার স্ট্রিং হয় 2 myapp foo bar?
সাইকোডাটা

4
পরামর্শ: sh কে BAT এ রূপান্তর করবেন না। পরিবর্তে, সাইগউইন ডাউনলোড করুন এবং পরিবর্তে এটি ব্যবহার করুন। অর্থাত্ আপনার শি স্ক্রিপ্টগুলি উইন্ডোজ মেশিনে কাজ করবে। এবং আপনাকে প্রতিটি শি'র বিএটি অনুবাদ করতে হবে না!
মার্টি ম্যাকগওয়ান

উত্তর:


107

কিছুটা গুগল করা উইকিবুক থেকে নিম্নলিখিত ফলাফল দেয় :

set argC=0
for %%x in (%*) do Set /A argC+=1

echo %argC%

দেখে মনে হচ্ছে সেমিডি.এক্সই পুরানো ডস দিনগুলি থেকে কিছুটা বিকশিত হয়েছে :)


7
নোট করুন যে এই রূপটি forকেবলমাত্র যুক্তিগুলির জন্য কাজ করে যা ফাইল নামগুলির মতো দেখায়, বিকল্প স্ট্রিং যেমন না -?। উদ্ধৃতি ( for %%i in ("%*") ...) ব্যবহার করা যুক্তির পক্ষে কাজ করে -?তবে আবার নেস্টেড কোটের কারণে উদ্ধৃত যুক্তিগুলির জন্য ব্যর্থ। একমাত্র দৃ way shift
়তম উপায়টি

4
MyBatchFile "*.*" "Abc"রিপোর্ট করে যে আরগসি == 9. - ডাউনভোটেড।
BrainSlugs83

এটি একটি ফাংশন হিসাবে 2500 টি আর্গুমেন্টে পরীক্ষা করে দেখেছেন এবং এটি একই আকারের অ্যারেগুলি সংজ্ঞায়িত করতে ব্যবহার করেছেন। ঠিক আমাকে কেন জিজ্ঞাসা করবেন না। বেশিরভাগ ক্ষেত্রে কেবল ব্যাচ কী সক্ষম তা শিখছে।
T3RR0R

45

আপনি এই ধরণের যুক্তি দিয়ে যুক্তির সংখ্যা হ্যান্ডেল করার ঝোঁক:

IF "%1"=="" GOTO HAVE_0
IF "%2"=="" GOTO HAVE_1
IF "%3"=="" GOTO HAVE_2

ইত্যাদি

আপনার যদি 9 টিরও বেশি যুক্তি থাকে তবে আপনি যদিও এই পদ্ধতির সাথে স্ক্রুড হন। কাউন্টার তৈরির জন্য বিভিন্ন হ্যাক রয়েছে যা আপনি এখানে দেখতে পাচ্ছেন , তবে সতর্ক হতে হবে এগুলি অজ্ঞান হৃদয়ের পক্ষে নয়।


6
আপনি এখনও shift9 টিরও বেশি ... এবং সমান-বর্ণিত কোডের 10 টি লাইন না রেখে গণনা করতে ব্যবহার করতে পারেন ।
জোয়ি 13

19

:getargcনীচের ফাংশনটি আপনি যা খুঁজছেন তা হতে পারে।

@echo off
setlocal enableextensions enabledelayedexpansion
call :getargc argc %*
echo Count is %argc%
echo Args are %*
endlocal
goto :eof

:getargc
    set getargc_v0=%1
    set /a "%getargc_v0% = 0"
:getargc_l0
    if not x%2x==xx (
        shift
        set /a "%getargc_v0% = %getargc_v0% + 1"
        goto :getargc_l0
    )
    set getargc_v0=
    goto :eof

এটি মূলত তালিকার উপরে একবার পুনরাবৃত্তি করে (যা ফাংশনের স্থানীয় যা শিফ্টগুলি মূল প্রোগ্রামে তালিকার পিছনে প্রভাব ফেলবে না), এটি শেষ না হওয়া পর্যন্ত এগুলি গণনা করে।

এটি একটি নিফটি ট্রিক ব্যবহার করে, ফাংশন দ্বারা সেট করা রিটার্ন ভেরিয়েবলের নামটি পাস করে।

মূল প্রোগ্রামটি কেবল এটি কীভাবে কল করা যায় তা চিত্রিত করে এবং তত্ক্ষণাত যুক্তিগুলি ইকো করে যে তারা যাতে অচ্ছুত রয়েছে তা নিশ্চিত করার জন্য:

C:\Here> xx.cmd 1 2 3 4 5
    Count is 5
    Args are 1 2 3 4 5
C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11
    Count is 11
    Args are 1 2 3 4 5 6 7 8 9 10 11
C:\Here> xx.cmd 1
    Count is 1
    Args are 1
C:\Here> xx.cmd
    Count is 0
    Args are
C:\Here> xx.cmd 1 2 "3 4 5"
    Count is 3
    Args are 1 2 "3 4 5"

আপনি এর ভিত্তিতে প্রবাহকে কীভাবে পরিবর্তন করতে পারবেন? (অন্যরকম প্রশ্ন হতে পারে তবে আমি মনে করি একটি সংক্ষিপ্ত উদাহরণ এখানে খুব সুবিধাজনক হবে!)
n611x007

@ n611x007 যেখানে echo Count is %argc%আপনি নিজের কোড সন্নিবেশ করিয়েছিলেন যা সেই গণনাটি যথাযথ কিনা তা পরীক্ষা করতে পারে এবং তারপরে এগিয়ে চলে যেতে পারে।
কেনে

7

এটা চেষ্টা কর:

SET /A ARGS_COUNT=0    
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1    
ECHO %ARGS_COUNT%

6
এই উত্তরটি কি কোনওভাবে @ নিম্রোডের থেকে আলাদা ? ...
ব্লু করে দিন

4
নিমরোডমে @ ফারডিনান্দবায়ার দ্বারা মন্তব্য পরীক্ষা করুন। ডাউনটাতে যাবে না কারণ আপনার 21 টি প্রতিনিধি 8)
n611x007

6

যদি আর্গুমেন্টের সংখ্যাটি একটি সঠিক সংখ্যা (কম বা 9 এর সমান) হওয়া উচিত, তবে এটি পরীক্ষা করার এটি একটি সহজ উপায়:

if "%2" == "" goto args_count_wrong
if "%3" == "" goto args_count_ok

:args_count_wrong
echo I need exactly two command line arguments
exit /b 1

:args_count_ok

2

আকার এবং পঠনযোগ্যতার ব্যয়ে shiftএকটি বা একটি forচক্র ব্যবহার করা এড়িয়ে যায় ।

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set /a arg_idx=1
set "curr_arg_value="
:loop1
if !arg_idx! GTR 9 goto :done
set curr_arg_label=%%!arg_idx!
call :get_value curr_arg_value !curr_arg_label!
if defined curr_arg_value (
  echo/!curr_arg_label!: !curr_arg_value!
  set /a arg_idx+=1
  goto :loop1
)
:done
set /a cnt=!arg_idx!-1
echo/argument count: !cnt!
endlocal
goto :eof

:get_value
(
  set %1=%2
)

আউটপুট:

count_cmdline_args.bat testing more_testing arg3 another_arg

%1: testing
%2: more_testing
%3: arg3
%4: another_arg
argument count: 4

সম্পাদনা: এখানে ব্যবহৃত "কৌশল" জড়িত:

  1. একটি স্ট্রিং তৈরি করা যা বর্তমানে মূল্যায়িত কমান্ড-লাইন আর্গুমেন্ট ভেরিয়েবল (যেমন "% 1", "% 2" ইত্যাদি) উপস্থাপন করে এমন একটি স্ট্রিং ব্যবহার করে যাতে শতাংশের অক্ষর ( %%) এবং একটি পাল্টা ভেরিয়েবল থাকেarg_idxপ্রতিটি লুপ পুনরাবৃত্তির জন্য ।

  2. সেই স্ট্রিংটি একটি ভেরিয়েবলের মধ্যে সংরক্ষণ করা curr_arg_label

  3. সেই স্ট্রিং ( !curr_arg_label!) এবং একটি রিটার্ন ভেরিয়েবলের নাম ( curr_arg_value) একটি আদিম সাবপ্রগ্রামে পাস করা get_value

  4. সাবপ্রগ্রামে এর প্রথম আর্গুমেন্টের ( %1) মান অ্যাসাইনমেন্টের বাম দিকে ( set) এবং তার দ্বিতীয় আর্গুমেন্টের ( %2) মান ডানদিকে ব্যবহৃত হয়। যাইহোক, যখন দ্বিতীয় সাবপ্রগ্রামের আর্গুমেন্টটি পাস হয় এটি কমান্ড ইন্টারপ্রেটার দ্বারা মূল প্রোগ্রামের কমান্ড-লাইন আর্গুমেন্টের মান হিসাবে সমাধান করা হয়। অর্থাত্, যা পাস হয়েছে, উদাহরণস্বরূপ, "% 4" নয় তবে চতুর্থ কমান্ড-লাইন আর্গুমেন্ট ভেরিয়েবলের যে পরিমাণ মান রয়েছে (নমুনা ব্যবহারের ক্ষেত্রে "another_arg")।

  5. তারপরে সাবপ্রগ্রামে রিটার্ন ভেরিয়েবল ( curr_arg_value) হিসাবে প্রদত্ত ভেরিয়েবল অপরিজ্ঞাত হওয়ার জন্য পরীক্ষা করা হয়, যা বর্তমানে মূল্যায়নকৃত কমান্ড-লাইন আর্গুমেন্ট অনুপস্থিত থাকলে ঘটবে। শুরুর দিকে এটি ছিল বর্গাকার বন্ধনীগুলিতে খালি স্কোয়ার বন্ধনীগুলিতে আবৃত রিটার্ন ভেরিয়েবলের মানটির তুলনা (যা আমি টেস্টিং প্রোগ্রাম বা সাবপ্রগ্রাম যুক্তিগুলির একমাত্র উপায় যা কোটস থাকতে পারে এবং ট্রায়াল-অ্যান্ড-ত্রুটি পর্যায়ের অবহেলিত বাকীটি ছিল) তবে যেহেতু এটি এখন কেমন ছিল তা স্থির ছিল।


4
যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কীভাবে এবং / বা কেন এটি সমস্যার সমাধান করে তা সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করলে উত্তরের দীর্ঘমেয়াদী মান উন্নত হবে।
ওয়েওওয়েওয়ের

@ তবুও আপনাকে ধন্যবাদ, আমি ভুলে যাচ্ছি যে অনেকের পক্ষে (সম্ভবত সংখ্যাগরিষ্ঠ) "স্ব-ব্যাখ্যামূলক" কোডের পরিবর্তে কোনও পাঠ্য বিবরণ দেওয়া ভাল।
ফেন-ফায়ার

@ ফেন-ফায়ার বাদে কোডটি স্ব-বর্ণনামূলক নয়।
লুডুভিজক

1

শেষ উত্তরটি এখন দু'বছর আগে, তবে আমার পক্ষে নয়টি কমান্ড লাইনের যুক্তির জন্য একটি সংস্করণ প্রয়োজন। অন্য একজনও হতে পারে ...

@echo off
setlocal

set argc_=1
set arg0_=%0
set argv_=

:_LOOP
set arg_=%1
if defined arg_ (
  set arg%argc_%_=%1
  set argv_=%argv_% %1
  set /a argc_+=1
  shift
  goto _LOOP
)
::dont count arg0
set /a argc_-=1
echo %argc_% arg(s)

for /L %%i in (0,1,%argc_%) do (
  call :_SHOW_ARG arg%%i_ %%arg%%i_%%
)

echo converted to local args
call :_LIST_ARGS %argv_%
exit /b


:_LIST_ARGS
setlocal
set argc_=0
echo arg0=%0

:_LOOP_LIST_ARGS
set arg_=%1
if not defined arg_ exit /b
set /a argc_+=1
call :_SHOW_ARG arg%argc_% %1
shift
goto _LOOP_LIST_ARGS


:_SHOW_ARG
echo %1=%2
exit /b

সমাধানটি প্রথম 19 টি লাইন এবং সমস্ত আর্গুমেন্টকে সি-এর মতো শৈলীতে ভেরিয়েবলগুলিতে রূপান্তর করে। অন্যান্য সমস্ত স্টাফ কেবল ফলাফলটি অনুসন্ধান করে এবং স্থানীয় আরগগুলিতে রূপান্তর দেখায়। আপনি যে কোনও কার্যক্রমে সূচি দ্বারা যুক্তিগুলি উল্লেখ করতে পারেন।


0

একটি শক্তিশালী সমাধান হ'ল সাবউরটিনের সাথে গণনা করা হচ্ছে call; সাবরুটিন ব্যবহার gotoবিবৃতি একটি লুপ যা অনুকরণ shiftiteratively এই (সাবরুটিন-শুধুমাত্র) আর্গুমেন্ট গ্রাস ব্যবহার করা হয়:

@echo off
setlocal

:: Call the argument-counting subroutine with all arguments received,
:: without interfering with the ability to reference the arguments
:: with %1, ... later.
call :count_args %*

:: Print the result.
echo %ReturnValue% argument(s) received.

:: Exit the batch file.
exit /b

:: Subroutine that counts the arguments given.
:: Returns the count in %ReturnValue%
:count_args
  set /a ReturnValue = 0
  :count_args_for

    if %1.==. goto :eof

    set /a ReturnValue += 1

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