首页 文章

批量到PowerShell语言转换

提问于
浏览
-1

我在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');
}

1 回答

  • 2

    变量:

    在PowerShell中,变量引用始终以_1664265为前缀(非常类似于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 粗略表示"loop recursively through filesystem tree"

    • for /f 粗略表示"loop through tokens in a file"

    应该注意的是,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 自然就是"return filename WITH extension" .

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

相关问题