Powershell 初心者で手探りで勉強しながら作っています
フォルダ内の複数のテキストファイル内の
あるキーワードを検索してそのキーワードから5行下に
検索したものとは別のキーワードがある場合は置換、
ない場合は何もしないを繰り返して
元のファイル名と違う名前でそれぞれ出力ということは出来ますか?
Select-string で検索してreplaceで置換すれば出来そうな気は
するのですが、上手くいかないので力を貸して頂ければと思います。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/20 22:52
回答1件
0
ベストアンサー
次のスクリプトを untitled.ps1 として保存してください。
ps1
1[CmdletBinding()] 2Param ( 3 [Parameter( 4 Mandatory = $true, 5 Position = 0, 6 ValueFromPipelineByPropertyName = $true 7 )] 8 [regex]$FirstPattern, 9 10 [Parameter( 11 Mandatory = $true, 12 Position = 1, 13 ValueFromPipelineByPropertyName = $true 14 )] 15 [regex]$SecondPattern, 16 17 [Parameter( 18 Mandatory = $true, 19 Position = 2, 20 ValueFromPipelineByPropertyName = $true 21 )] 22 [string]$Replacement, 23 24 [Parameter( 25 Mandatory = $false, 26 Position = 3, 27 ValueFromPipelineByPropertyName = $true 28 )] 29 [ValidateRange(1, [int]::MaxValue)] 30 [int]$Count = 5, 31 32 [Parameter( 33 Mandatory = $true, 34 Position = 4, 35 ValueFromPipelineByPropertyName = $true, 36 ValueFromPipeline = $true, 37 ValueFromRemainingArguments = $true 38 )] 39 [string[]]$InputObject 40) 41Begin { 42 $phase = 0 43} 44Process { 45 if ($phase -eq $Count) { 46 $InputObject -replace $SecondPattern, $Replacement 47 } else { 48 $InputObject 49 } 50 if ($phase -ne 0 -or $_ -match $FirstPattern) { 51 $phase++ 52 } 53}
次にテスト用のデータを作ります。
1..10 | Foreach-Object { "foo","bar" } > old.txt
old.txt を開き、foo bar が交互に 10 回並んでいることを確かめてください。
問題無ければ置換します。
Get-Content .\old.txt | .\untitled.ps1 bar . x
置換結果は画面に表示されます。
7 行目の foo が xxx に置換されているはずです。
.\untitled.ps1 bar . x
は三つの引数 bar
.
x
を取ります。
最初の bar
は最初に発見する文字列です。
これが二行目にあるので、実際に置換するのはその五行後の七行目ということになります。
.
は正規表現で任意の一文字の意味です。これを x
に置換します。
この結果、七行目の foo が xxx になります。
これを新しいファイルに保存するには次のようにします。
Get-Content .\old.txt | .\untitled.ps1 bar . x > new.txt
一番目の引数と二番目の引数が正規表現であることに気を付けてください。
追記
二度の仕様追加の要件を満たすもののはずです。これ以降、仕様の追加があるのであれば、この質問は解決済みにして自分で実装してください。それでどうしてもわからなければまた改めて新しい質問を立ててください。
ps1
1[CmdletBinding()] 2Param ( 3 [Parameter( 4 Mandatory = $true, 5 Position = 0, 6 ValueFromPipelineByPropertyName = $true 7 )] 8 [regex]$FirstPattern, 9 10 [Parameter( 11 Mandatory = $true, 12 Position = 1, 13 ValueFromPipelineByPropertyName = $true 14 )] 15 [regex]$SecondPattern, 16 17 [Parameter( 18 Mandatory = $true, 19 Position = 2, 20 ValueFromPipelineByPropertyName = $true 21 )] 22 [string]$Replacement, 23 24 [Parameter( 25 Mandatory = $false, 26 Position = 3, 27 ValueFromPipelineByPropertyName = $true 28 )] 29 [ValidateRange(0, [int]::MaxValue)] 30 [int]$Count = 5, 31 32 [Parameter( 33 Mandatory = $true, 34 Position = 4, 35 ValueFromPipelineByPropertyName = $true, 36 ValueFromPipeline = $true, 37 ValueFromRemainingArguments = $true 38 )] 39 [string[]]$InputObject 40) 41Begin { 42 $replace = @() 43 $line = 1 44} 45Process { 46 if ($InputObject -match $FirstPattern) { 47 $replace += ($line + $Count) 48 } 49 if ($replace -contains $line) { 50 $InputObject -replace $SecondPattern, $Replacement 51 $replace = $replace -gt $line 52 } else { 53 $InputObject 54 } 55 $line++ 56}
投稿2019/06/21 04:04
編集2019/06/21 11:56総合スコア28669
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/21 07:05
2019/06/21 07:20 編集
2019/06/21 09:38
2019/06/21 09:43
2019/06/21 09:53
2019/06/21 11:00 編集
2019/06/21 11:40
2019/06/21 12:26
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。