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

我在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。如果您能帮助转换,我们将不胜感激

编辑后:

以下是我的原始批处理脚本:

@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"
}