Saving command arguments to array batch – Stack Overflow

Saving command arguments to array batch

Здесь нет функций-членов массива для сортировки, длины или других операций, как в других языках, поэтому пакетные сценарии Windows не поддерживают функциональность массивов. По этому вопросу Аачини написал исчерпывающий обзор.

Однако вы можете достаточно хорошо смоделировать массивы, чтобы достичь того, что вы описываете.

@echo off
:: arr.bat -- simulates creation of an array with script arguments
setlocal enabledelayedexpansion

set args=%*
set arr.length=0

rem delayed expansion of %args% here to prevent if statement from freaking out
rem if quotation marks or spaces are encountered
if #!args!==# goto :usage

rem ###############
rem construct array
rem ###############

rem surround each argument with quotation marks and loop through them
rem 1 "2 3" 4 becomes "1" ""2" "3"" "4" (keeping 2 and 3 grouped)
for %%I in ("%args: =" "%") do (

    rem Pop quiz, hotshot.  Why did I not just use `set arr[!arr.length!]=%%~I`
    rem to strip the quotation marks?  Try it and see what happens.
    set val=%%I
    set arr[!arr.length!]=!val:"=!

    rem incrememt %array.length%
    set /a arr.length=!arr.length!   1
)

rem ##############
rem retrieve array
rem ##############

echo arr[] has a length of %arr.length%.

rem arr.Ubound is the highest index in the array.  For instance, if the array
rem has 4 elements, then !arr[%arr.Ubound%]! refers to %arr[3]%.
set /a arr.Ubound=%arr.length% - 1
for /L %%I in (0, 1, %arr.Ubound%) do (

    rem To retrieve an array element, expand the inner variable immediately
    rem while delaying expansion of the outer variable.
    echo arr[%%I] = !arr[%%I]!
)

goto :EOF

:usage
echo Usage: %~nx0 [arg [arg [arg]]] etc.

Вот некоторые примеры результатов.

C:UsersmeDesktop>arr
Usage: arr.bat [arg [arg [arg]]] etc.

C:UsersmeDesktop>arr 1 "2 3" 4
arr[] has a length of 3.
arr[0] = 1
arr[1] = 2 3
arr[2] = 4

C:UsersmeDesktop>arr the quick brown fox jumps over the lazy dog, and so forth.
arr[] has a length of 12.
arr[0] = the
arr[1] = quick
arr[2] = brown
arr[3] = fox
arr[4] = jumps
arr[5] = over
arr[6] = the
arr[7] = lazy
arr[8] = dog,
arr[9] = and
arr[10] = so
arr[11] = forth.

Using arrays in batch files

One thing the batch language does not use is strongly typed variables.
In batch files, everything is a string, and a string can be anything ranging from numbers to commands.
This may be a weak point of the batch language, it can also be used to your advantage by creating “Q&D” (Quick & Dirty) solutions that would never be possible in other languages.

:/>  Скачать Shazam на ПК или ноутбук Windows 7, 8, 10 бесплатно

Having worked with several other scripting languages, I really did miss (associative) arrays in the batch language.
On this page I’ll show you how, in Windows NT 4 and later, to use sets of variables like they were (associative) arrays or hashtables.

Теперь в приглашении DOS должна появиться следующая команда:

SET User

The result will probably look like this:

USERDOMAIN=YOURPC
USERNAME=You
USERPROFILE=C:Documents and SettingsYou

Попробуйте еще раз:

SET Pro

Конечный результат, скорее всего, будет выглядеть примерно так:

PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 14 Stepping 8, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0e08
ProgramFiles=C:Program Files
PROMPT=$P$G

Попробуем перебрать все переменные PROCESSOR_*, как если бы они были элементами массива (в пакетных файлах используйте ECHO вместо @ECHO и %%A вместо %A):

FOR /F "tokens=2* delims=_=" %A IN ('SET PROCESSOR_') DO @ECHO PROCESSOR %A  :  %B

Вот что вы получите:

PROCESSOR ARCHITECTURE  :  x86
PROCESSOR IDENTIFIER  :  x86 Family 6 Model 14 Stepping 8, GenuineIntel
PROCESSOR LEVEL  :  6
PROCESSOR REVISION  :  0e08

Там приведен весь список переменных PROCESSOR_*.

To create your own arrays, I suggest using dots instead of underscores, and maybe prefix the name with a double underscore.
The following command uses WMIC and a “Q&D” batch shortcut to store all properties of harddisk partition C: in an array-like set of environment variables, and uses FOR /F to loop through this array-like set of variables:

FOR /F "tokens=*" %%A IN ('WMIC LogicalDisk Where "DeviceID='C:'" Get /Format:list ^| FIND "="') DO (
	SET __LogicalDiskC.%%A
)

Или если мы хотим сохранить только те переменные, которые не имеют пустых значений:

FOR /F "tokens=*" %%A IN ('WMIC LogicalDisk Where "DeviceID='C:'" Get /Format:list ^| FINDSTR /R /C:"=."') DO (
	SET __LogicalDiskC.%%A
)

You may be surprised to find that these commands have different results.
After all, one might ask, aren’t environment variables that get an empty value discarded?
That’s right, but WMIC behaves a bit quirky, and its supposedly empty values still contain CR/LF pairs (Carriage Return/Line Feed, or “Enter”), so they will show up, even if they seem to have no value assigned.

:/>  Инструкция. Как в Windows 10 добавить “Мой компьютер” на рабочий стол? | RuCore.NET - 2021

Now, type:

SET __LogicalDiskC.

Для получения списка всех значений, которые мы только что сохранили:

__LogicalDiskC.Caption=C:
__LogicalDiskC.Compressed=FALSE
__LogicalDiskC.CreationClassName=Win32_LogicalDisk
__LogicalDiskC.Description=Local harddisk
__LogicalDiskC.DeviceID=C:
__LogicalDiskC.DriveType=3
__LogicalDiskC.FileSystem=NTFS
__LogicalDiskC.FreeSpace=20930985984
__LogicalDiskC.MaximumComponentLength=255
__LogicalDiskC.MediaType=12
__LogicalDiskC.Name=C:
__LogicalDiskC.QuotasDisabled=TRUE
__LogicalDiskC.QuotasIncomplete=FALSE
__LogicalDiskC.QuotasRebuilding=FALSE
__LogicalDiskC.Size=31453437952
__LogicalDiskC.SupportsDiskQuotas=TRUE
__LogicalDiskC.SupportsFileBasedCompression=TRUE
__LogicalDiskC.SystemCreationClassName=Win32_ComputerSystem
__LogicalDiskC.SystemName=YOURPC
__LogicalDiskC.VolumeDirty=FALSE
__LogicalDiskC.VolumeName=System
__LogicalDiskC.VolumeSerialNumber=3647DF7B

To loop through all values, use the same, slightly modified FOR /F loop again:

FOR /F "tokens=2* delims=.=" %%A IN ('SET __LogicalDiskC.') DO ECHO Drive C: %%A = %%B

И смотри:

Drive C: Caption = C:
Drive C: Compressed = FALSE
Drive C: CreationClassName = Win32_LogicalDisk
Drive C: Description = Local harddisk
Drive C: DeviceID = C:
Drive C: DriveType = 3
Drive C: FileSystem = NTFS
Drive C: FreeSpace = 20931293184
Drive C: MaximumComponentLength = 255
Drive C: MediaType = 12
Drive C: Name = C:
Drive C: QuotasDisabled = TRUE
Drive C: QuotasIncomplete = FALSE
Drive C: QuotasRebuilding = FALSE
Drive C: Size = 31453437952
Drive C: SupportsDiskQuotas = TRUE
Drive C: SupportsFileBasedCompression = TRUE
Drive C: SystemCreationClassName = Win32_ComputerSystem
Drive C: SystemName = YOURPC
Drive C: VolumeDirty = FALSE
Drive C: VolumeName = System
Drive C: VolumeSerialNumber = 3647DF7B

Instead of just ECHOing, you can use the variables any other way you want.

Возможно, это самое близкое к (ассоциативным) массивам, к чему когда-либо приблизится пакетный язык.

Оставьте комментарий

Adblock
detector