Eliminazione di intere righe in un file di testo basato su una corrispondenza di stringa parziale con Windows PowerShell


22

Quindi ho diversi file di testo di grandi dimensioni che devo ordinare e rimuovere tutte le occorrenze di righe che contengono una determinata parola chiave. Quindi sostanzialmente, se ho queste righe:

Questo non è un test
Questo è un test
Forse un test
Sicuramente non è un test

Ed eseguo lo script con 'not', devo eliminare completamente le righe 1 e 4.

Ho provato con:

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

ma sostituisce solo il "Programma" e non l'intera riga.

Risposte:


25

Ecco cosa farei:

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

La linea di Snark fa lo stesso, ma inizia con il caricamento di tutti i file in un array, il che può essere problematico con file di grandi dimensioni in termini di memoria.


Suggerirei di utilizzare Set-Content anziché Out-File, il primo si occupa di dati non elaborati e non taglierà stringhe o formatterà oggetti.
JasonMArcher,

@JasonMArcher Puoi pubblicare un esempio usando Set-Content? Non credo che Set-Contentsia un sostituto drop-in per Out-File.
Iain Samuel McLean Elder,

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Out-File è fondamentalmente Set-Content, ma esegue l'input attraverso la formattazione predefinita anziché la semplice conversione di stringhe.
JasonMArcher,

Ho avuto lo stesso identico problema e la tua risposta è il 99% di ciò di cui ho bisogno. Il problema finale è che sto eseguendo il comando in un ciclo con una variabile $ (sostituendo 'non' nel tuo esempio). Se codifico una stringa, funziona perfettamente; ma se uso una variabile non fa nulla. Qualche idea sul perché? Ho provato sia la variabile nuda sia inserendola tra "virgolette"
Stephen R,

Come può essere modificato per sostituire il testo su quelle righe
Tom

7

Questo funzionerà:

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

Questo restituisce solo una singola riga nel secondo file chiamato True.

Correzione: questo restituisce solo una singola riga nel secondo file composta da 'Vero'. Forse manca "Foreach-Object {$ _", quindi viene eseguito una volta per riga? Modifica: Beh, in realtà è irrilevante ora, ha cancellato il file che speravo di chiarire. Grazie comunque per l'aiuto, ma sono ancora curioso di sapere quale sarebbe il comando corretto in modo da poterlo fare in futuro?

1
Funziona per me con le tue 4 linee di test sopra.
Snark

2
non lo farebbe mai sovrascrivere il file originale!
user33788

3
d'accordo, ma ho usato gli stessi nomi di file usati dal poster originale, per facilitare la risposta. Ha usato co2.txt sia per input che per output.
Snark,

0

Puoi anche usare 'Select-String' con l'opzione -notmatch:

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

0

Avevo solo bisogno di farlo funzionare e ho pensato a quanto segue:

$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 chiave è che il 'Where-Object' usando un blocco di script (come indicato dalle parentesi graffe) richiede di dichiarare la variabile in un evento di creazione del blocco di script, quindi il

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

linea.

Strutturandola in questo modo, è possibile creare una funzione, passarle una stringa di testo per farle corrispondere parzialmente, eseguire la creazione del blocco di script con il valore passato e farlo funzionare correttamente.

Le risposte sopra non spiegano correttamente come passare il valore da sostituire all'interno di una variabile.


Puoi spiegare (più chiaramente) come è meglio della risposta (molto più concisa) di Snark ? Si prega di non rispondere nei commenti; modifica la tua risposta per renderla più chiara e completa.
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.