我以前从来没有使用过powershell,谷歌也没有给我确切的答案。我希望你们能帮助我。我需要找到目录(包括子目录)中包含2行的所有文件:
aaa aaa
bbb bbb并将第二行替换为ccc
如果行bbb bbb没有紧跟在aaa aaa之后,就不应该进行替换。
这是我到目前为止所知道的:
$line3 = "aaa[ ]*aaa[ ]*bbb[ ]*bbb"
Get-ChildItem -exclude *.bak -recurse *.txt | Where-Object {$_.Attributes -ne "Directory"} |
    ForEach-Object { 
        Copy-Item $_ "$($_).bak"; 
        $wholeFile = [IO.File]::ReadAllText("$_");
        $wholeFile = $wholeFile.replace("`n", " ");
        $wholeFile = $wholeFile.replace("`r", " ");
        $temp3 = $wholeFile | Select-String -pattern $line3 -quiet;
        if(($temp3 -eq "True")){
            (Get-Content $_)  -replace "bbb[ ]*bbb", "ccc" | Set-Content -path $_;
        }
        else{
            echo failed
        }
    }我认为这个代码几乎可以工作,除非文件有两次"bbb bbb":一次紧跟在"aaa aaa“之后,另一次没有"aaa aaa”。这两行都会被替换,我只需要第一行是replaced.Is,有什么方法可以修复它吗?有更多经验的人能告诉我我是否遗漏了什么吗?有没有更简单/更短的解决方案来满足我的需求?我在powershell中见过很多整洁的单行解决方案。我的案子有没有类似的东西?谢谢
发布于 2012-12-15 03:00:25
我想这会做你想要的。这不是一行,我相信它可以被简化。不过,我更担心的是获得一些功能性的东西。
我也测试了你的用例。只有当'bbb bbb‘行紧跟在' aaa’行之后时,它才会被替换。文件中包含该行的所有其他位置都不会被覆盖。
只需使用您的测试信息修改顶部的变量即可。
我一直认为你会的:
#script variables
$filePath     = 'C:\Temp\SO\'
$processFiles = Get-ChildItem -Exclude *.bak -Filter *.txt -Recurse -Path $filePath
$query        = 'aaa aaa'
$query2       = 'bbb bbb'
$replace      = 'ccc'
#script begin
foreach ( $file in $processFiles ) {
    #Pre-Processing | backup the file for archival
    $file | Copy-Item -Destination "$file.bak"
    $arrayData = Get-Content $file
    for ($i=0; $i -lt $arrayData.Count; $i++)
    {
        if ( $arrayData[$i] -match $query ) {
            if ( $arrayData[$i+1] -match $query2 ) {
                $arrayData[$i+1] = $arrayData[$i+1].Replace($query2,$replace)
            }
            else {
                #Catch if the second query isn't matched.
            }
        }
        else {
            #Catch if the first query isn't matched.
        }
    }
    #Overwrites the original text file that was being processed
    $arrayData | Out-File $file -Force
}发布于 2012-12-15 00:58:56
这是一个批处理解决方案:)
@echo off
setlocal enabledelayedexpansion
cd C:\folder
set aaa=false
for /r C:\folder %%a in (*) do (
for /f "tokens=1,2 delims= " %%x in (%%a) do (
if "!aaa!"=="true" (
if "%%x"=="bbb" if "%%y"=="bbb" (
echo ccc ccc >>temp.txt
del %%a /f /q
ren temp.txt %%~nxa
set aaa=false
)
) else (
if "%%x"=="aaa" if "%%y"=="aaa" set aaa=true
echo %%x %%y >>temp.txt
)
)
)发布于 2013-07-26 18:05:50
下面是一个简单的解决方案:
$a="aaa aaa";$b="bbb bbb";$c="ccc";ls *.txt -File -Recurse|foreach{$l=0;cp $_ "$($_).bak";(cat $_)|foreach{if($_ -match $a){$l=1;$_}else{if($_ -match $b){if($l -eq 1){$_ -replace($b,$c)}else{$_};$l=2}else{$l=0;$_}}}|sc($_) -Force}它有点晦涩难懂,我不会称之为“整洁”,但它是有效的。
https://stackoverflow.com/questions/13882047
复制相似问题