批量到PowerShell语言转换

时间:2015-08-27 18:26:01

标签: 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 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');
}

1 个答案:

答案 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
}

For循环:

在cmd中,for循环结构的行为会有所不同,具体取决于第一个开关:

  • for /r大致意味着“通过文件系统树递归循环”
  • for /f大致意味着“在文件中循环标记”

应该注意,cmd for循环使用参数,由前缀%%表示(例如%%G%%i

PowerShell没有这个概念,只是在循环中使用变量。因此,您的for /rfor /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视为路径,给我完整的根路径”

同样,$fileFileInfo对象的事实派上用场,可以从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"
}