Windows 批处理到PowerShell语言转换
我在DOS中的批处理脚本处理速度很慢,所以有人建议我使用powershell。我现在是第一次在windows上运行它,但在今天之前我从未使用过它。我听说它类似于批处理脚本,所以我目前正在将批处理脚本转换为powershell脚本。下面是我到目前为止转换一半的脚本:Windows 批处理到PowerShell语言转换,windows,powershell,batch-file,cmd,Windows,Powershell,Batch File,Cmd,我在DOS中的批处理脚本处理速度很慢,所以有人建议我使用powershell。我现在是第一次在windows上运行它,但在今天之前我从未使用过它。我听说它类似于批处理脚本,所以我目前正在将批处理脚本转换为powershell脚本。下面是我到目前为止转换一半的脚本: # ask user for network share and file that they would like to search $textFilePath = Read-Host Please enter filesyste
# ask user for network share and file that they would like to search
$textFilePath = Read-Host Please enter filesystem location of "filenames.txt". Include drive letter or // at start of path
$uncPath = Read-Host Please enter the UNC path you would like to search. Include // at start of path.
# REM check if network path is available. If it is, search network directory for files with same name as the strings in filenames.txt
IF (Test-Path %uncPath%) {
echo Network Path Exists. Searching %uncPath% for files with same name and extension as filenames in the filenames.txt file
for (/r %uncPath% %%G IN (*)) {for (/F "tokens=*" %%i in (%textFilePath%)) {if (%%~nxG==%%i) {echo %%~nxG,%%~fG >> filenamesOutput.txt}}}
pause
}
IF (!(Test-Path exist %uncPath%)) {
echo File not found
GOTO:userInput
}
我目前正在学习powershell命令,并将批处理命令更改为powershell。如果您能帮助转换,我们将不胜感激
编辑后:
以下是我的原始批处理脚本:
@echo off
echo Please enter filesystem location of "filenames.txt". (Include Drive letter or // at start of path)
set /p textFilePath=Enter The Value:%=%
:userInput
REM ask user for network share and file that they would like to search
echo Please enter the UNC path you would like to search. (Include // at start of path)
set /p uncPath=Enter The Value:%=%
REM check if network path is available. If it is, search network directory for files with same name as the strings in filenames.txt
IF exist %uncPath% (
echo Network Path Exists. Searching %uncPath% for files with same name and extension as filenames in the filenames.txt file
for /r %uncPath% %%G IN (*) DO for /F "tokens=*" %%i in (%textFilePath%) DO if %%~nxG==%%i echo %%~nxG,%%~fG >> filenamesOutput.txt
pause
)
IF NOT exist %uncPath% (
echo File not found
GOTO:userInput
)
第二次编辑后:
$VerbosePreference = "continue"
# ask user for network share and file that they would like to search
$textFilePath = Read-Host Please enter filesystem location of "filenames.txt". Include drive letter or // at start of path
$uncPath = Read-Host Please enter the UNC path you would like to search. Include // at start of path.
# check if network path is available. If it is, search network directory for files with same name as the strings in filenames.txt
IF (Test-Path $uncPath){
echo "Network Path Exists. Searching $uncPath for files with same name and extension as filenames in the filenames.txt file"
foreach($file in Get-ChildItem $uncPath -Recurse) {
# Get-Content reads in a file, line by line
foreach($line in Get-Content $_.FullName) {
# if goes in here
if($file.Name -eq $line){
echo $file.Name
"{0},{1}" -f $file.Name,$file.FullName | Out-File filenamesOutput2.txt -Append
}
}
}
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}
IF (!(Test-Path $uncPath)){
echo "UNC path not found"
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}
变量:
在PowerShell中,变量引用的前缀总是$
(与PHP或Perl中的情况非常相似)
因此,在cmd/batch中分配和取消引用的任何变量如下:
set /p varname= somevalue
echo %varname%
PowerShell中的将被视为(请注意,赋值和取消引用之间没有区别):
因此,您的存在
/测试路径
语句应该是:
if(Test-Path $uncPath){
# Loops in here
# "#" starts is a single-line comment btw
}
For循环: 在cmd中,根据第一个开关的不同,for循环构造的
行为不同:
for/r
大致意思是“通过文件系统树递归循环”
for/f
大致意思是“循环文件中的令牌”
需要注意的是,cmd for循环使用前缀%%
表示的参数(如示例中的%%G
或%%i
)
PowerShell没有这个概念,只是在循环中使用变量。因此,您的for/r
和for/f
循环变成:
# Get-ChildItem is equivalent to the "dir" command
# The -Recurse is pretty self-explanatory ( = /S)
foreach($file in Get-ChildItem $uncPath -Recurse) {
# Get-Content reads in a file, line by line
foreach($line in Get-Content $textFilePath) {
# if goes in here
}
}
参数修改器:
在cmd中,参数(如%%G
)后面可以跟一系列修饰符
%%~nG
表示“将%%G
视为路径,返回不带扩展名的名称”
%%~xG
表示“将%%G
视为路径,返回文件扩展名”
因此,%%~nxG
自然意味着“返回扩展名为的文件名”
在PowerShell中,所有内容都是.NET对象,对于$file
,它是一个对象。从FileInfo
对象中,文件名(带扩展名)存储在Name
属性中,因此您的if
语句:
if %%~nxG==%%i
变成:
if($file.Name -eq $line){
# echo and output goes in here
}
%%~fG
表示“将%%G
视为一个路径,给我完整的根路径”
同样,由于$file
是FileInfo
对象,因此可以从FullName
属性访问完整路径:
"{0},{1}" -f $file.Name,$file.FullName | Out-File filenamesOutput.txt -Append
-f
操作符是.NET版本的sprintf
的简化语法快捷方式
最终导致如下结果:
# ask user for network share and file that they would like to search
$textFilePath = Read-Host 'Please enter filesystem location of "filenames.txt". Include drive letter or \\ at start of path'
$uncPath = Read-Host 'Please enter the UNC path you would like to search. Include \\ at start of path.'
# check if network path is available. If it is, search network directory for files with same name as the strings in filenames.txt
if (Test-Path $uncPath) {
Write-Host "Network Path Exists. Searching $uncPath for files with same name and extension as filenames in the filenames.txt file"
foreach($file in Get-ChildItem $uncPath) {
foreach($line in Get-Content $textFilePath) {
if($file.Name -eq $line){
'"{0}","{1}"' -f $file.Name,$file.FullName | Out-File filenamesOutput.txt -Append
}
}
}
pause
} else {
Write-Host "File not found"
}
使用原始批处理脚本可能比使用混合脚本更容易:)@MathiasR.Jessen抱歉。我没想过。包括我原来的批脚本上面。这是这么多的信息,谢谢!我的脚本是用powershell编写的,除了一行,第13行带有echo语句。对于该行,我是将$file.Name
和$file.Fullname
回显到一个文本文件中,并在它们之间加一个逗号以写入该文本文件,还是使用写入主机
?如果使用写入主机
,则该字符串将直接写入主机(控制台窗口),并且永远不会出现在文件中。在我的回答中,“{0}”-f$var
表达式构造了一个字符串,然后通过管道传输到Out File
cmdlet,该cmdlet将其写入文件。今天我将阅读更多内容并对其进行消化,但感谢您提供的所有信息,我很快学到了很多。在格式字符串周围使用单引号:“{0}”,“{1}”“-f$file.Name,$file.FullName
或使用两个连续的双引号对双引号进行转义:“{0}”、“{1}”“”-f$file.Name,$file.FullName
# ask user for network share and file that they would like to search
$textFilePath = Read-Host 'Please enter filesystem location of "filenames.txt". Include drive letter or \\ at start of path'
$uncPath = Read-Host 'Please enter the UNC path you would like to search. Include \\ at start of path.'
# check if network path is available. If it is, search network directory for files with same name as the strings in filenames.txt
if (Test-Path $uncPath) {
Write-Host "Network Path Exists. Searching $uncPath for files with same name and extension as filenames in the filenames.txt file"
foreach($file in Get-ChildItem $uncPath) {
foreach($line in Get-Content $textFilePath) {
if($file.Name -eq $line){
'"{0}","{1}"' -f $file.Name,$file.FullName | Out-File filenamesOutput.txt -Append
}
}
}
pause
} else {
Write-Host "File not found"
}