Eliminar líneas enteras en un archivo de texto basado en una coincidencia de cadena parcial con Windows PowerShell

22

Por lo tanto, tengo varios archivos de texto grandes que necesito clasificar y eliminar todas las apariciones de líneas que contienen una palabra clave determinada. Básicamente, si tengo estas líneas:

Esto no es una prueba
Esto es una prueba
Tal vez una prueba
Definitivamente no es una prueba

Y ejecuto el script con 'no', necesito eliminar por completo las líneas 1 y 4.

He estado intentando con:

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

pero solo reemplaza el 'Programa' y no toda la línea.

karel
fuente

Respuestas:

25

Esto es lo que haría:

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

La línea de Snark hace lo mismo, pero comienza cargando todo el archivo en una matriz, lo que puede ser problemático con los archivos grandes en cuanto a memoria.

buti-oxa
fuente
Sugeriría que use Set-Content en lugar de Out-File, el primero trata con datos sin procesar y no corta cadenas ni formatea objetos.
JasonMArcher
@JasonMArcher ¿Puedes publicar un ejemplo usando Set-Content? No creo que Set-Contentsea ​​un reemplazo directo Out-File.
Iain Samuel McLean Élder
Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Out-File es básicamente Set-Content, pero ejecuta la entrada a través del formato predeterminado en lugar de la simple conversión de cadena.
JasonMArcher
Tuve exactamente el mismo problema y tu respuesta es el 99% de lo que necesito. El último problema es que estoy ejecutando el comando en un bucle con una variable $ (reemplazando 'no' en su ejemplo). Si codifico una cadena, funciona perfectamente; pero si uso una variable no hace nada. ¿Alguna idea de por qué? He intentado tanto la variable desnuda como ponerla entre "comillas"
Stephen R
¿Cómo se puede modificar esto para reemplazar el texto en esas líneas
Tom
7

Esto funcionará:

(Get-Content "D:\Logs\co2.txt") -notmatch "not" | Out-File "D:\Logs\co2.txt"
Snark
fuente
Esto solo devuelve una sola línea en el segundo archivo llamado True.
Corrección: Esto solo devuelve una sola línea en el segundo archivo que consiste en 'Verdadero'. ¿Tal vez le falta el "Foreach-Object {$ _" para que se ejecute una vez por línea? Editar: Bueno, en realidad es irrelevante ahora, borró el archivo que esperaba borrar. Gracias por la ayuda de todos modos, pero todavía tengo curiosidad por saber cuál sería el comando correcto para poder hacer esto en el futuro.
1
A mí me funciona con tus 4 líneas de prueba anteriores.
Snark
2
nunca lo haría sobrescribir el archivo original!
user33788
3
Acepté, pero utilicé los mismos nombres de archivo que los utilizados en el póster original, para facilitar la respuesta. Usó co2.txt tanto para entrada como para salida.
Snark
0

También puede usar 'Seleccionar cadena' con la opción -notmatch:

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

Solo necesitaba que esto funcionara y se me ocurrió lo siguiente:

$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

La clave es que el 'Objeto Where' que usa un bloque de script (como se indica con las llaves) requiere declarar la variable en un evento de creación de bloque de script, de ahí el

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

línea.

Al estructurarlo de esta manera, se puede crear una función, pasarle una cadena de texto para que coincida parcialmente, realizar la creación del bloque de script con el valor pasado y hacer que funcione correctamente.

Las respuestas anteriores no explican correctamente cómo pasar el valor a reemplazar dentro de una variable.

Walkabout Tigger
fuente
¿Puedes explicar (más claramente) cómo esto es mejor que la respuesta de Snark (mucho más concisa) ? Por favor no responda en los comentarios; edite su respuesta para que sea más clara y completa.
Scott