Мне нравится использовать один из упакованных файлов HOSTS (MVPS,), чтобы защитить себя от некоторых из более неприятных доменов. К сожалению, иногда эти файлы для меня немного переусердствуют (иногда блокировка googleadsservices - это боль). Мне нужен простой способ вырезать определенные строки из этих файлов. В Linux я использую:
cat hosts |grep -v <pattern> >hosts.new
И файл перезаписывается за вычетом строк, относящихся к шаблону, который я указал в grep. Поэтому я просто установил его для замены hosts на hosts.new при перезагрузке, и все готово.
Есть ли простой способ сделать это в PowerShell?





В PowerShell вы бы сделали
(Get-Content hosts) -notmatch $pattern | Out-File hosts.new
или
(cat hosts) -notmatch $pattern > hosts.new
кратко.
Конечно, поскольку Out-File (а вместе с ним и оператор перенаправления) по умолчанию использует формат Unicode, вы действительно можете захотеть использовать Set-Content вместо Out-File:
(Get-Content hosts) -notmatch $pattern | Set-Content hosts.new
или
(gc hosts) -notmatch $pattern | sc hosts.new
И поскольку входной файл читается в выражении группировки (круглые скобки вокруг Get-Content hosts), вы можете записать результат обратно в исходный файл:
(Get-Content hosts) -notmatch $pattern | Set-Content hosts
В дополнение к Полезный ответ Ансгара Вихерса (который предлагает прагматичные и лаконичные решения, основанные на чтении всего входного файла в память заранее):
Эквивалент PowerShell для grep - это Командлет Select-String, и, как и grep, он напрямую принимает аргумент имени файла (синтаксис PSv3 +):
Select-String -NotMatch <pattern> hosts | ForEach-Object Line | Set-Content hosts.new
Select-String -NotMatch <pattern> hosts - это сокращение от
.
Select-String -NotMatch -Pattern <pattern> -LiteralPath hosts и является виртуальным эквивалентом grep -v <pattern> hosts
Однако Select-String не выводит струны, он выводит экземпляры [Microsoft.PowerShell.Commands.MatchInfo], соответствующие строкам заворачивать (хранящиеся в свойстве .Line) вместе с метаданными о совпадении.
ForEach-Object Line извлекает из этих объектов только совпадающие строки (значение свойства .Line).
Set-Content hosts.new записывает совпадающие строки в файл hosts.new, используя кодировку "ANSI" в Windows PowerShell, т. Е. Использует устаревшую кодовую страницу, подразумеваемую активным языковым стандартом системы, как правило, наднациональный 8-битный расширенный набор ASCII - и кодировку UTF-8 (без BOM) в PowerShell Основной.
Используйте параметр -Encoding, чтобы указать другую кодировку.
>, напротив (эффективный псевдоним Командлет Out-File), создает:
> hosts.new вместо | Set-Content hosts.new подойдет.Примечание: хотя и > / Out-File, и Set-Content подходят для отправки входных данных нить в выходной файл, они обычно не подходят для отправки других типов данных в файл для обработки программный: выходные объекты > / Out-Fileкак они будут печатать на консоли / терминале, что является довольно форматом для отображать , тогда как Set-Contentукрепляет (проще говоря: вызывает .ToString()) входные объекты, что часто приводит к потере информации.
Export-CliXml), JSON (ConvertTo-Json) или CSV (Export-Csv).