Видалення цілих рядків у текстовому файлі на основі часткового збігу рядків з Windows PowerShell


22

Тож у мене є кілька великих текстових файлів, які мені потрібно сортувати, і видалити всі зустрічі рядків, що містять задане ключове слово. Отже, якщо у мене є ці рядки:

Це не тест
Це тест
Можливо тест
Однозначно не тест

І я запускаю сценарій з "не", мені потрібно повністю видалити рядки 1 і 4.

Я намагався:

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

але він замінює лише "Програму", а не весь рядок.

Відповіді:


25

Ось що я б робив:

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

Рядок Snark робить те ж саме, але він починається з завантаження всього файлу в масив, що може бути проблематично для великих файлів з пам'яттю.


Я б запропонував вам використовувати Set-Content замість Out-File, колишні операції із сировинними даними та не відрізати рядки чи об’єкти форматування.
JasonMArcher

@JasonMArcher Чи можете ви розмістити приклад, використовуючи Set-Content? Я не вірю, що Set-Contentце замінна платіжна система Out-File.
Ієн Самуель Маклін Старший

Get-Content .\in.txt | Where-Object {$_ -notmatch 'not'} | Set-Content out.txt Вихідний файл - це в основному Set-Content, але він виконує введення через форматування за замовчуванням замість простого перетворення рядків.
JasonMArcher

У мене була точно така ж проблема, і ви відповідаєте - це 99% того, що мені потрібно. Остаточне питання полягає в тому, що я запускаю команду в циклі зі змінною $ (замінюючи "не" у вашому прикладі). Якщо я жорстко кодую рядок, він справно працює; але якщо я використовую змінну, вона нічого не робить. Будь-яка ідея чому? Я спробував як голу змінну, так і помістивши її в "цитати"
Stephen R

Як це можна змінити, щоб замінити текст у цих рядках
Том

7

Це спрацює:

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

Це просто повертає один рядок у другому файлі під назвою True.

Виправлення. Це просто повертає один рядок у другому файлі, що складається з "True". Може, у ньому відсутній "Foreach-Object {$ _", тому він працює один раз на рядок? Редагувати: Ну, насправді це не має значення, вона стерла файл, який я сподівався очистити. Дякую за допомогу в будь-якому випадку, але мені все одно цікаво, якою була б правильна команда, щоб я могла це зробити в майбутньому?

1
Це працює для мене з вашими 4 тестовими лініями вище.
Снарк

2
ніколи б не перезаписати оригінальний файл!
користувач33788

3
погодився, але я використав ті ж назви файлів, що й оригінальний плакат, щоб полегшити відповідь. Він використовував co2.txt і для вводу, і для виводу.
Снарк

0

Ви також можете використовувати "Select-String" з опцією -notmatch:

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

0

Мені просто потрібно було працювати, і я придумав таке:

$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

Ключовим моментом є те, що "Де-Об'єкт", що використовує блок скриптів (позначений фігурними дужками), вимагає оголосити змінну в події створення блоку скрипту, отже

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

рядок.

Структурувавши його таким чином, можна створити функцію, передати їй текстовий рядок, щоб частково збігатися, виконати створення блоку скриптів із переданим значенням та дозволити йому правильно працювати.

Наведені вище відповіді неправильно пояснюють, як передавати значення, яке слід замінити в змінній.


Чи можете ви пояснити (чіткіше), як це краще, ніж відповідь Снарка (набагато більш стислий) ? Будь ласка, не відповідайте на коментарі; відредагуйте свою відповідь, щоб зробити її більш зрозумілою та повною.
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.