Usuwanie całych linii w pliku tekstowym na podstawie częściowego dopasowania ciągu z Windows PowerShell


22

Mam więc kilka dużych plików tekstowych, które muszę posortować i usunąć wszystkie wystąpienia wierszy zawierających dane słowo kluczowe. Zasadniczo, jeśli mam te linie:

To nie jest test
To jest test
Być może test
Zdecydowanie nie test

I uruchamiam skrypt z „nie”, muszę całkowicie usunąć wiersze 1 i 4.

Próbowałem z:

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

ale zastępuje tylko „Program”, a nie całą linię.

Odpowiedzi:


25

Oto co bym zrobił:

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

Linia Snarka robi to samo, ale zaczyna się od załadowania całego pliku do tablicy, co może być problematyczne w przypadku dużych plików pod względem pamięci.


Sugerowałbym, abyś używał Set-Content zamiast Out-File, ten pierwszy dotyczy surowych danych i nie będzie odcinał ciągów ani formatował obiektów.
JasonMArcher

@JasonMArcher Czy możesz opublikować przykład za pomocą Set-Content? Nie wierzę, że Set-Contentto zastępczy zamiennik Out-File.
Iain Samuel McLean Starszy

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Plik wyjściowy jest w zasadzie zestawem treści, ale uruchamia dane wejściowe za pomocą domyślnego formatowania zamiast prostej konwersji łańcucha.
JasonMArcher

Miałem dokładnie ten sam problem, a ty odpowiadasz na 99% tego, czego potrzebuję. Ostatni problem polega na tym, że uruchamiam polecenie w pętli ze zmienną $ (zastępując w tym przykładzie „nie”). Jeśli koduję na stałe ciąg znaków, działa on idealnie; ale jeśli użyję zmiennej, nic nie robi. Masz pomysł, dlaczego? Próbowałem zarówno samej zmiennej, jak i wpisując ją w „cudzysłów”
Stephen R

Jak można to zmienić, aby zastąpić tekst w tych wierszach
Tom

7

To zadziała:

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

To po prostu zwraca pojedynczą linię w drugim pliku o nazwie True.

Korekta: Zwraca tylko jeden wiersz w drugim pliku składającym się z „True”. Czy może brakuje mu „Foreach-Object {$ _”, więc działa raz na linię? Edycja: Cóż, właściwie to teraz nie ma znaczenia, usunęło plik, który miałem nadzieję wyczyścić. W każdym razie dziękuję za pomoc, ale nadal jestem ciekawy, jakie byłoby prawidłowe polecenie, aby móc to zrobić w przyszłości?

1
Działa dla mnie z twoimi 4 liniami testowymi powyżej.
Snark

2
nigdy nie nadpisze oryginalnego pliku!
user33788

3
Zgodziłem się, ale użyłem tych samych nazw plików, które zostały użyte w oryginalnym plakacie, aby ułatwić odpowiedź. Używał co2.txt zarówno dla wejścia jak i wyjścia.
Snark

0

Możesz także użyć „Select-String” z opcją -notmatch:

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

0

Musiałem tylko to uruchomić i wymyśliłem następujące rzeczy:

$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

Kluczem jest to, że „Where-Object” wykorzystujący blok skryptu (oznaczony nawiasami klamrowymi) wymaga zadeklarowania zmiennej w zdarzeniu tworzenia bloku skryptu, stąd

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

linia.

Konstruując go w ten sposób, można utworzyć funkcję, przekazać ciąg tekstowy w celu częściowego dopasowania, wykonać tworzenie bloku skryptu z przekazaną wartością i pozwolić mu działać poprawnie.

Powyższe odpowiedzi nie wyjaśniają poprawnie, jak przekazać wartość, która ma zostać zastąpiona w zmiennej.


Czy możesz wyjaśnić (jaśniej), w jaki sposób jest to lepsze niż odpowiedź Snarka (o wiele bardziej zwięzła) ? Proszę nie odpowiadać w komentarzach; edytuj swoją odpowiedź, aby była jaśniejsza i bardziej kompletna.
Scott
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.