Powershell - 仅保留txt文件中包含某些选定单词的行

Powershell - 仅保留txt文件中包含某些选定单词的行

我有一个 txt 文件,我只想保留其中的几行

我想要一个命令来把这个

txt文件:

;FFMETADATA1
title=TNT
disc=01
comment=
lyrics-eng=
\

\

\
album=Classic
genre=Older
artist=ACDC
encoder=Lavf59.17.102

变成这样:

;FFMETADATA1
title=TNT
encoder=Lavf59.17.102

我使用了此链接中的命令:

仅保留 txt 文件中含有特定单词/字符的行(Powershell)(Windows 批处理文件)

PowerShell -Command "gci *.txt | foreach { (cat $_.FullName | ? { $_ -like '*;FFMETADATA1*' }) | set-content $_.FullName}"

但是txt文件看起来像这样:

;FFMETADATA1

如何使用命令使txt文件包含行;FFMETADATA1 title= 和coder=?

答案1

您的命令基本正确,或者可以说您走在正确的道路上。但是-like您应该使用-match和正则表达式。'METADATA|title|encoder'将返回 txt 中与 3 个字符串中的任何一个匹配的任何行。因此命令将是:

如果你想创建一个新文件:

cat .\su.txt | ? { $_ -match 'METADATA|title|encoder' } | set-content .\su2.txt

如果要将其保存在同一个文件中:

(cat .\su.txt | ? { $_ -match 'METADATA|title|encoder' }) | set-content .\su.txt

对于目录中的所有文件:

gci *.txt | foreach { (cat $_.fullname | ? { $_ -match 'METADATA|title|encoder' }) | set-content $_.fullname  }

? (Where-Object)如果我们要进行代码高尔夫,我们甚至可以通过删除(并使用scfor set-content- 你实际上不应该使用别名那么多,因为它使内容更难阅读,但现在我已经在进行代码高尔夫了,我无法停止)来使其更短

(cat .\su.txt) -match 'METADATA|title|encoder' | sc bla.txt

您可以随时调整正则表达式,使其更加具体。例如:';FFMETADATA1|title=TNT|encoder=Lavf59.17.102'

如果你的正则表达式读起来很乱,可以用 PowerShell 帮你创建

$Regex = @(
    ";FFMETADATA1",
    "title=TNT",
    "encoder=Lavf59.17.102"
) -join '|'

(cat .\su.txt) -match $Regex | set-content bla.txt

编辑:根据 OP 的要求 - 如何通过 cmd 并使用隐藏的 PS 窗口运行它:

PowerShell -WindowStyle Hidden -Command "gci *.txt | foreach { (cat $_.fullname | ? { $_ -match 'METADATA|title|encoder' }) | set-content $_.fullname  }"

答案2

您可以使用以下脚本来获取所需内容。将其保存为 .ps1 文件并执行,或直接将其粘贴到 powershell 中并按回车键。

不要忘记编辑路径。

$files = Get-ChildItem "C:\Temp\test" -Filter "*.txt"

$files | ForEach-Object {
    $content = Get-Content -path $_.FullName -Force
    
    $newfile = @()

    $matches = @(
        ";FFMETADATA1"
        "title="
        "encoder="
    )

    $content | ForEach-Object {
        $line = $_

        $matches | ForEach-Object {
            if( $line.StartsWith($_) ) 
            {
                $newfile += $line
            }
        }
    }

    rename-item -Path $_.FullName -NewName "$($_.FullName).old"
    
    $newfile | Out-File $_.FullName
}

答案3

为此,使用 PowerShell 比 Batch 更容易。

- 快捷方式

$Text    = ".\text.txt"
$toKeeps = ';FFMETADATA1', 'title=TNT', 'encoder=Lavf59.17.102'
$Null > $Text
$toKeeps | % {$_} >> $Text

- 无备份

$Text    = ".\text.txt"
$toKeeps = ';FFMETADATA1', 'title=TNT', 'encoder=Lavf59.17.102'
$NewText = cat $Text | ? {$_ -in $toKeeps}
$Null > $Text
$NewText | % {$_} >> $Text

- 具有备份

$Text   = ".\text.txt"
$Backup = "$($Text).bak"
if ( !(Test-path $Text) )   {'File not found'; pause; exit 0}
if ( !(Test-path $Backup) ) {Copy-Item $Text $Backup}
$toKeeps = @(";FFMETADATA1"; "title=TNT"; "encoder=Lavf59.17.102")
$NewText = Get-Content $Text | Where {$_ -in $toKeeps}
$Null > $Text
$NewText | ForEach {$_} >> $Text

它们的输出:

;FFMETADATA1
title=TNT
encoder=Lavf59.17.102

相关内容