我在DOS下的批处理脚本是处理慢的方法,所以有人推荐我使用PowerShell。我第一次在Windows上运行它,但是我从来没有在今天之前使用它。我听说它与批处理脚本类似,所以我目前正在将我的批处理脚本转换为PowerShell脚本。到目前为止,下面是我的脚本转换的一半:
# 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。欢迎转换帮助。
AF编辑:
这是我原来的批处理脚本:
@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');
}
答案 0 :(得分:2)
在PowerShell中,变量引用始终以$
为前缀(非常类似于PHP或Perl)。
因此,您将在cmd / batch中分配和取消引用的任何变量为:
set /p varname= somevalue
echo %varname%
将PowerShell视为(注意分配和解除引用之间没有区别):
$varname = "varvalue"
Write-Host $varname
因此,您的exists
/ Test-Path
语句应为:
if(Test-Path $uncPath){
# Loops in here
# "#" starts is a single-line comment btw
}
在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
)可以是modified using a tilde (~
),后跟一系列修饰符。
%%~nG
表示“将%%G
视为路径,返回不带扩展名的名称”%%~xG
表示“将%%G
视为路径,返回文件扩展名”所以%%~nxG
自然意味着“返回带有扩展名的文件名”。
在PowerShell中,一切都是.NET对象,对于$file
,它是一个FileInfo
对象。从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
运算符是String.Format
的简化语法快捷方式,.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"
}