批次檔中的Powershell命令:從文字檔案中刪除除帶有「foo」和「bar」的行之外的所有行?

批次檔中的Powershell命令:從文字檔案中刪除除帶有「foo」和「bar」的行之外的所有行?

我有一個包含以下 3 行的文字檔:

This line contains foo.
This line contains bar.
This line has neither.

我可以在“.bat”檔案(上面的“.txt”檔案旁邊)中執行以下命令,它會刪除文字檔案中除包含“foo”的行之外的所有行:

Powershell.exe -Command "gci *.txt | foreach { (cat $_.FullName | ? { $_ -like '*foo*' }) | set-content $_.FullName}"

運行它就達到了預期的效果,在文字檔案中只留下這一行:

This line contains foo.

現在的問題是:如果我想保留包含「foo」的行怎麼辦行中的「酒吧」?

到目前為止,我一定已經嘗試過大約 40 或 50 種不同的組合,放置管道字元:*foo*|*bar*,取出星號foo|bar,僅在開頭和結尾放置星號:*foo|bar*,使用逗號,不使用逗號,使用分號,不使用分號、-like使用或不使用分號重複指令$_ 以及許多其他方式。

沒有任何效果- 到目前為止,在每次嘗試中,我最終得到的文本文件看起來都一樣,原始三行包含foo (第1 行)、bar (第2 行),但兩者都不包含(第3 行)。

為了確保我沒有編輯命令並犯錯誤,我會定期刪除我的編輯並再次運行該命令,以僅取出沒有“foo”的行並且它可以工作,或者我只是再次粘貼該命令,再次測試它,然後開始嘗試編輯它以包含“bar”,但無濟於事。

我最近已經問過這個問題,但我想我的標題措辭不清楚。有人試圖回答這個問題,但他們提供的每個答案都不起作用,至少當我將命令放入批次檔並在文字檔案旁邊運行它時,也許它對他們有用,使用不同的方法我是誰,我不知道。

請注意,我在批次檔中使用 powershell 命令!我沒有在控制台中輸入或使用 ps1 腳本。 我不需要做任何事情,因為我上面提到的第一個命令確實有效刪除所有帶有“foo”的行。

顯然,由於這確實有效,因此該命令可以用作添加的基礎,因此它可以在一個命令中處理“foo”和“bar”。

當然,除非這是 100% 不可能的——在大約 4 天后嘗試了 40 或 50 個不同的命令變體之後——我開始懷疑!

如果有人回答這個問題,請發布一個批次檔命令,就像我上面的一樣。請不要告訴我改用 ps1 腳本或給出解釋在控制台視窗中輸入內容的答案。

我上面發布的命令只需要某種修改,這樣“bar”就可以添加到“foo”,這樣它就可以處理多個文字字串。

這之所以如此困難,似乎是因為如果您運行命令來取出除“foo”之外的所有行,那麼您已經取出了帶有“bar”的行。我懷疑這就是為什麼還沒有人提出可行的解決方案,也許根本就沒有一個。

預先感謝任何有有效答案的人。通常情況下,這些問題在這裡都能很快得到解答,或者我只是不斷嘗試不同的方法,然後讓它發揮作用——但這次不是,出於某種原因,這是一個非常困難的問題。

答案1

只需使用兩個單獨的條件並用 OR 連接即可:

cat $_.FullName | ? { $_ -like '*foo*' -or $_ -like '*bar*' }

括號可以用來增加清晰度,但它們是可選的:

{ ($_ -like '*foo*') -or ($_ -like '*bar*') }

像我上面那樣發布一個批次檔命令。請不要告訴我改用 ps1 腳本或給出解釋在控制台視窗中輸入內容的答案。

這些其實是同一件事。無論您如何呼叫 PowerShell 腳本,無論它是儲存在檔案中還是透過命令列傳遞或透過鍵盤輸入,它仍然是 PowerShell 腳本,並且遵循相同的語法規則。

答案2

您可以使用select-string正規表示式來代替:

gci *.txt | % { (cat $_.FullName | select-string -pattern 'foo|bar') | set-content $_.FullName -Force }

select-string如果需要的話,允許您執行更複雜的正規表示式匹配。


進一步閱讀

相關內容