Powershell – keep only lines in txt files contain some selected words

batchcommand linepowershellwindows

I have a txt file and I would like to keep only a few lines in it

I want to a command that turns this

txt file:

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

\

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

Into this:

;FFMETADATA1
title=TNT
encoder=Lavf59.17.102

I used the command in this link:

Keep only lines in txt files that contain a certain word/character (Powershell) (Windows batch file)

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

But the txt file looked like this:

;FFMETADATA1

How to use the command to make the txt file have lines ;FFMETADATA1 title= and encoder= ?

Best Answer

Your command is basically correct, or let's say you're on the right path. But instead of -like you should use -match and a regex. 'METADATA|title|encoder' would return any line in your txt that matches any of the 3 strings. So the command would be:

If you want to create a new file:

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

If you want to save it in the same file:

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

For all files in your directory:

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

If we'd be code golfing, we could even make it shorter by dropping the ? (Where-Object) (and use sc for set-content - you shouldn't actually use aliases that much because it makes stuff harder to read but I'm now already code golfing i can't stop)

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

You can always adjust the regex, to be more specific. e.g: ';FFMETADATA1|title=TNT|encoder=Lavf59.17.102'

and if your regex gets to messy to read, let PowerShell create it for you

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

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

Edit: As per OPs request - How to run this via cmd and with a hidden PS window:

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