2

これまで powershell を使用したことがなく、Google は私が必要としている正確な答えをくれませんでした。皆さんが私を助けてくれることを願っています。次の 2 行のディレクトリ (サブディレクトリを含む) 内のすべてのファイルを検索する必要があります。

aaa aaa
bbb bbb

2行目を次のように置き換えます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」が 2 回出現する場合を除いて、このコードはほとんど機能すると思います。両方の行が置き換えられ、最初の行だけを置き換える必要があります.それを修正する方法はありますか? 私が何かを見逃した場合、より経験豊富な人が教えてくれますか? 私が必要としているものに対して、より簡単で短い解決策はありますか? 私は、powershell で非常に多くのきちんとした 1 行のソリューションを見てきました。私の場合、そのようなことはありますか?ありがとう

4

3 に答える 3

2

これはあなたが望むことをすると思います。これはワンライナーではなく、単純化できると確信しています。しかし、私は何かを機能させることにもっと心配していました。

私もあなたのユースケースをテストしました。これは、「aaa aaa」行の直後に続く「bbb bbb」行のみを置き換えます。その行を含むファイル内の他のすべての場所は上書きされません。

テスト用の情報で上部の変数を変更するだけです。

私はいつもあなたが次のことをするだろうと思っていました:

  1. .txt ファイルのみを処理する
  2. データ行全体のクエリ/置換
#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-14T19:00:24.833 に答える
0

ワンライナーソリューションは次のとおりです。

$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}

少しあいまいで、「きちんとした」とは言えませんが、機能します。

于 2013-07-26T10:05:50.093 に答える