如何从Windows传统命令行移动到现代PowerShell?
我习惯了Windows中的一些命令行技巧,这些技巧大大提高了我的工作效率 现在我被告知我应该搬到PowerShell,因为它更强大。我花了一段时间才掌握了一些技巧(对象、管道等),并且有很多关于如何完成一些事情的优秀教程。 然而,一些(相对)基本的技巧仍然困扰着我。例如,PowerShell中For结构的等价物是什么 比如说,如何从Windows传统命令行移动到现代PowerShell?,powershell,Powershell,我习惯了Windows中的一些命令行技巧,这些技巧大大提高了我的工作效率 现在我被告知我应该搬到PowerShell,因为它更强大。我花了一段时间才掌握了一些技巧(对象、管道等),并且有很多关于如何完成一些事情的优秀教程。 然而,一些(相对)基本的技巧仍然困扰着我。例如,PowerShell中For结构的等价物是什么 比如说, FOR %i IN (*.jpg) DO Convert %i -resize 800x300 resized/%i 上面这一行拍摄文件夹中的所有照片,并使用Image
FOR %i IN (*.jpg) DO Convert %i -resize 800x300 resized/%i
上面这一行拍摄文件夹中的所有照片,并使用ImageMagick的转换工具调整图像大小,并将调整大小的图像恢复到称为resized的子文件夹中
在PowerShell中,我尝试了以下命令:
Dir ./ | foreach {convert $_.name -resize 800x300 resized/$_name}
尽管我在谷歌上搜索了这么多,但这是行不通的。缺少什么?使用:
Get-ChildItem | foreach {convert $_.name -resize 800x300 resized/$($_.name)}
或者,您可能需要传递全名(带路径),同时显示较短的语法(使用别名):
此外,您可能希望提供可执行文件的完整路径。根据下面给出的注释进行修订 有许多名为“Convert”的应用程序。如果我这样做 在我的电脑上。它向我显示了一个属于Windows系统的应用程序。如果PowerShell在你身上运行了错误的应用程序,它将永远无法工作 解决方案是将PowerShell指向ImageMagick程序文件夹中的转换工具。谷歌搜索“ImageMagick PowerShell”会让你找到许多与你面临相同问题的人。请注意,此答案中使用的路径分隔符是
/
,而不是\
,这也适用于Windows,并使代码与跨平台PowerShell核心版本兼容
tl;博士:
$convertExe = './convert' # adjust path as necessary
Get-ChildItem -File -Filter *.jpg | ForEach-Object {
& $convertExe $_.Name -resize 800x300 resized/$($_.Name)
}
请继续阅读以获取解释和背景信息
相当于:
FOR %i IN (*.jpg)
是:
或者,使用PowerShell自己的通配符表达式(速度较慢,但功能更强大):
如果您不担心将匹配限制为文件(而不是目录),Get Item*.jpg
也可以
虽然dir
是Get ChildItem
的内置别名,但我建议您习惯PowerShell自己的别名,它遵循一致的命名约定;e、 例如,PowerShell自己的Get ChildItem
别名是gci
此外,在脚本中,最好始终使用完整的命令名,以提高可读性和健壮性
正如您所发现的,要在循环中处理匹配的文件,您必须将Get ChildItem
命令的输出通过管道(
)传输到ForEach Object
cmdlet,并向其传递为每个输入对象执行的脚本块({…}
),其中,$\uu
指的是手边的输入对象
(foreach
是foreach对象
的内置别名,但请注意,还有一个foreach
语句,其工作方式不同,不要混淆两者。)
来自cmd.exe
(批处理文件)世界的人有两个陷阱:
- 在PowerShell中,出于安全原因,仅按文件名引用可执行文件(例如,
)不会按当前目录中的该名称执行可执行文件转换
- 只能通过文件名执行路径中的可执行文件,除非您特别将ImageMagick的
放在路径中SYSTEM32目录之前的目录中,否则标准的Windowsconvert.exe
实用程序(其目的是将FAT磁盘卷转换为NTFS)将被调用。convert.exe
使用
查看提交Get Command convert
时实际执行的操作convert
显示PATH环境变量的当前值(相当于$env:PATH
)echo%PATH%
- 如果自定义的
确实在当前目录中,请将其作为convert.exe
调用-即,必须明确引用其位置/convert
- 否则(您的
或者根本不在路径中,或者被其他实用程序隐藏)根据需要指定可执行文件的路径,但是请注意,如果在变量中引用该路径,或者使用单引号或双引号的字符串(例如,如果路径包含空格,这是必需的),您必须使用调用操作符convert.exe
调用,例如&
或和$convertExe…
和“$HOME/ImageMagic 2/convert”…
- 只能通过文件名执行路径中的可执行文件,除非您特别将ImageMagick的
- PowerShell通过管道而不是字符串发送对象(这项创新是PowerShell功能的核心)。当引用对象的属性或元素作为较大字符串的一部分时,必须将表达式括在
中,子表达式运算符:$(…)
-正确:包含在已调整大小/$($.Name)
$(…)
-!!不正确的-resized/$\uu.Name
本身被字符串化,后跟literal$\u
。Name
- 但是,请注意,独立的属性/索引引用或甚至方法调用不需要
;例如,在问题中的命令中使用的$(…)
本身可以工作,并保留其原始类型(未字符串化)$名称
- 但是,请注意,独立的属性/索引引用或甚至方法调用不需要
- 请注意,没有属性/索引访问权限的变量(如
本身)不需要$\uU
,但在本例中,$(…)
将扩展到完整路径。在大多数情况下,包含变量引用的无引号标记$\uU
$convertExe = './convert' # adjust path as necessary Get-ChildItem -File -Filter *.jpg | ForEach-Object { & $convertExe $_.Name -resize 800x300 resized/$($_.Name) }
FOR %i IN (*.jpg)
Get-ChildItem -File -Filter *.jpg
Get-ChildItem -File -Path *.jpg # specifying parameter name -Path is optional