Windows PowerShellとの部分的な文字列一致に基づいてテキストファイルの行全体を削除する


22

そのため、並べ替える必要があるいくつかの大きなテキストファイルがあり、特定のキーワードを含む行のすべての出現を削除します。基本的に、これらの行がある場合:

これはテストではない
これはテストである
多分テストである
間違いなくテストではない

そして、「not」でスクリプトを実行します。1行目と4行目を完全に削除する必要があります。

私が試してきました:

PS C:\Users\Admin> (Get-Content "D:\Logs\co2.txt") | 
Foreach-Object {$_ -replace "3*Program*", ""} | 
Set-Content "D:\Logs\co2.txt"

ただし、行全体ではなく、「プログラム」のみを置き換えます。

回答:


25

ここに私がやることがあります:

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt

Snarkの行も同じことをしますが、すべてのファイルを配列にロードすることから始まります。これは、大きなファイルをメモリ単位で使用すると問題になる場合があります。


Out-Fileの代わりにSet-Contentを使用することをお勧めします。Out-Fileは、生データを処理し、文字列やフォーマットオブジェクトを切り捨てません。
ジェイソンマーチャー

@JasonMArcherを使用して例を投稿できますSet-Contentか?私はそれSet-Contentがドロップインの代わりになるとは思わないOut-File
イアンサミュエルマクリーン長老

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Out-Fileは基本的にSet-Contentですが、単純な文字列変換ではなく、デフォルトのフォーマットを使用して入力を実行します。
ジェイソンマーチャー

私はまったく同じ問題を抱えていましたが、答えは私が必要とするものの99%です。最後の問題は、$ variableを使用してループでコマンドを実行していることです(この例では「not」を置き換えます)。文字列をハードコーディングすると、完全に機能します。しかし、変数を使用しても何もしません。理由は何ですか?裸の変数と「引用符」に入れて両方を試しました
スティーブンR

これはどのように変更することができ置き換えるそれらのライン上のテキストを
トム・

7

これは動作します:

(Get-Content "D:\Logs\co2.txt") -notmatch "not" | Out-File "D:\Logs\co2.txt"

これは、Trueという名前の2番目のファイルに1行を返すだけです。

修正:これは、2番目のファイルに「True」で構成される1行を返すだけです。「Foreach-Object {$ _」が欠落している可能性があるため、1行に1回実行されますか?編集:まあ実際にはそれは無関係です、それは私が片付けたいと思っていたファイルを消去しました。とにかく助けてくれてありがとう、しかし私はまだ正しいコマンドがどうなるのか興味があります。

1
上記の4つのテストラインで機能します。
スナーク

2
元のファイルを上書きすることはありません!
user33788

3
同意しましたが、答えを簡単にするために、元のポスターで使用したものと同じファイル名を使用しました。彼は、入力と出力の両方にco2.txtを使用しました。
スナーク

0

また、-notmatchオプションで 'Select-String'を使用することもできます。

Select-String 'not' .\input.txt -notmatch | % {$_.Line} | set-content output.txt

0

これを機能させるために必要なのは、次のことです。

$InServerName = 'SomeServerNameorIPAddress'
$InFilePath = '\Sharename\SomePath\'
$InFileName = 'Filename.ext'

$OutServerName = 'SomeServerNameorIPAddress'
$OutFilePath = '\Sharename\SomePath\'
$OutFileName = 'Filename.out'

$InFile = -join('\\',$InServerName,$InFilePath,$InFilename)
$OutFile = -join('\\',$OutServerName,$OutFilePath,$OutFilename)
$FindStr = 'some string to match on'
$CompareStr = [scriptblock]::Create($FindStr)
$CompareStr
Get-Content $InFile | Where-Object {$_ -notmatch $CompareStr} | Set-Content $OutFile
Get-Content $OutFile

重要なのは、スクリプトブロックを使用する「Where-Object」(中括弧で示されている)では、スクリプトブロック作成イベントで変数を宣言する必要があるため、

$CompareStr = [scriptblock]::Create($FindStr)

ライン。

このように構造化することにより、関数を作成し、部分的に一致するテキスト文字列を渡し、渡された値を使用してスクリプトブロックの作成を実行し、正常に機能させることができます。

上記の答えは、変数内で置換される値を渡す方法を正しく説明していません。


これがSnarkの(はるかに簡潔な)答えよりも優れていることを(より明確に)説明できますか?コメントで返信しないでください。回答を編集して、より明確で完全なものにします。
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.