Убрать строки из текстового файла на основе содержимого - PullRequest
0 голосов
/ 04 сентября 2018

Мне нравится использовать один из упакованных файлов HOSTS (MVPS), чтобы защитить себя от некоторых более неприятных доменов. К сожалению, иногда эти файлы немного переусердствуют для меня (блокировка googleadsservices иногда является болью). Я хочу простой способ вырезать определенные строки из этих файлов. В Linux я использую:

cat hosts |grep -v <pattern> >hosts.new

И файл перезаписывается за вычетом строк, ссылающихся на шаблон, который я указал в grep. Поэтому я просто настроил его для замены hosts на hosts.new при перезагрузке, и все готово.

Есть ли простой способ сделать это в PowerShell?

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

В дополнение к Полезный ответ Ансгара Вихера (который предлагает прагматичные и краткие решения, основанные на предварительном чтении всего входного файла в память):

Эквивалент grep в PowerShell - это 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 (без спецификации) в PowerShell Core .
    Используйте параметр -Encoding, чтобы указать другую кодировку.

    • >, напротив (эффективный псевдоним Out-File командлет ), создает:

      • UTF16-LE ("Unicode") файлы по умолчанию в Windows PowerShell .
      • файлы UTF-8 (без спецификации) в PowerShell Core - другими словами: в PowerShell Core с использованием
        > hosts.new вместо | Set-Content hosts.new сделает.
    • Примечание. Хотя оба > / Out-File и Set-Content подходят для отправки string входных данных в выходной файл, они обычно не подходят для отправка других типов данных в файл для программной обработки: > / Out-File выходных объектов так, как они будут печататься на консоли / терминале , что довольно неплохо для display , тогда как Set-Content преобразует (проще говоря: вызывает .ToString() on) входные объекты, что часто приводит к потере информации.

      • Для нестроковых данных рассмотрите (более) формат структурированных данных, таких как XML (Export-CliXml), JSON (ConvertTo-Json) или CSV (Export-Csv).
0 голосов
/ 04 сентября 2018

В 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...