Очень часто нам приходится совершать некую операцию над группой объектов — файлов, процессов, текстовых строк, и т.д. Делать это в PowerShell можно разными способами. Например For:
# Получаем объекты представляющие файлы в переменную $files $Files = dir C:roottest # С помощью for: # 1) объявляем переменную $i, и присваиваем ей значение 0 # 2) указываем условие повторения цикла($i меньше количества файлов) # 3) указываем что после каждого выполнения цикла надо увеличить $i на единицу for ($i=0; $i -lt $files.Count; $i++) { # Пока условие удовлетворяется, вызываем утилиту md5.exe, передавая ей в # качестве аргумента элемент массива файлов под номером $i (отсчет идет с 0) md5.exe $files[$i] }
И вот результат:
For очень популярен, присутствует во множестве языков, но тем не менее обладает некоторыми недостатками. Во первых это необходимость использования временной переменной для перебора, во вторых — излишняя сложность конструкции. Гораздо проще для перебора группы объектов использовать ForEach:
# Получаем объекты представляющие файлы в переменную $files $Files = dir C:roottest # Каждый объект из $Files по очереди помещается в переменную $File ForEach ($File in $Files) { # ... и выполняется блок кода... md5.exe $File }
Или еще короче:
Способ отличный, но тоже не лишен недостатков. Обычно работая в консоли я сначала выполняю команду dir или get-*, для того чтобы посмотреть на список объектов, а затем уже хочу обработать их. Для использования ForEach мне пришлось бы возвращаться в начало строки, дописывать там Foreach ($obj in ( затем идет код получения объектов, затем закрывающие скобки и затем уже код для выполнения. Не слишком удобно для быстрой работы. Но к счастью есть командлет Foreach-Object. В него можно просто перенаправить полученные объекты, и указать блок кода для выполнения. При этом даже не нужно указывать имя для временного объекта — он всегда будет представлен под именем $_
Так как этот командлет предназначен в первую очередь для интерактивной работы, то у него есть два псевдонима: ForEach (хоть и почти идентичен ранее упомянутому ключевому слову, путать их не стоит) и % (знак процента). Вот это уже гораздо удобнее для работы в шелле, хоть и выглядит страшновато для непосвященных
Удобнее может быть только использование PowerShell’овских командлетов или скриптов умеющих обрабатывать объекты получаемые по конвейеру. Тут уже не надо никаких For и Foreach
На самом деле я изложил тут лишь одно применение переменной $_ (кстати она называется «Default variable»), хоть и наиболее популярное. $_ используется еще во многих местах, обычно представляя «текущий объект». Но думаю теперь вам будет проще понять и эти случаи. Например в командлете Where-Object $_ исполняет ту же роль что и в ForeEach-Object — содержит текущий объект конвейера. А в блоке обработки ошибок (trap), за $_ будет скрываться объект текущей ошибки.
Ваш комментарий будет первым