Команда Powershell в пакетном файле: удалить все строки из текстового файла, кроме строк с «foo» и «bar»?

Команда Powershell в пакетном файле: удалить все строки из текстового файла, кроме строк с «foo» и «bar»?

У меня есть текстовый файл с этими тремя строками:

This line contains foo.
This line contains bar.
This line has neither.

Я могу запустить следующую команду в файле «.bat» (рядом с указанным выше файлом «.txt»), и она удалит все строки в текстовом файле, кроме строк, содержащих «foo»:

Powershell.exe -Command "gci *.txt | foreach { (cat $_.FullName | ? { $_ -like '*foo*' }) | set-content $_.FullName}"

Запуск этой команды даёт ожидаемый эффект, оставляя в текстовом файле только эту строку:

This line contains foo.

Теперь проблема: что делать, если я хочу сохранить строки, содержащие «foo»и«bar» в строке?

До сих пор я перепробовал, наверное, 40 или 50 различных комбинаций: добавлял символ вертикальной черты: *foo*|*bar*, убирал звездочки foo|bar, добавлял звездочки только в начале и в конце: *foo|bar*, использовал запятую, не использовал запятую, использовал точку с запятой, не использовал точку с запятой, дублировал -likeкоманду с символом и без него $_ и многими другими способами.

Ничего не работает — при каждой попытке до сих пор я получал один и тот же текстовый файл, в котором исходные три строки содержали foo (строка 1), bar (строка 2) и none (строка 3).

Чтобы убедиться, что я не редактирую команду и не совершаю ошибку, я периодически удаляю свои правки и снова запускаю команду, чтобы просто убрать строки без «foo», и это работает, или просто снова вставляю команду, снова проверяю ее, а затем начинаю пытаться редактировать ее, чтобы включить «bar», но безрезультатно.

Я уже задавал этот вопрос недавно, но, полагаю, моя формулировка заголовка была неясной. Кто-то пытался ответить на него, но каждый предоставленный ими ответ не сработал, по крайней мере, когда я помещаю команду в пакетный файл и запускаю ее рядом с текстовым файлом, возможно, это работает для них, используя другой метод, нежели тот, который использую я, я не знаю.

Обратите внимание, что я использую команду PowerShell в пакетном файле!Я не печатаю в консоли и не использую скрипты PS1. Мне не нужно ничего этого делать, потому что самая первая команда, которую я упомянул выше,работаетчтобы удалить все строки с "foo".

Очевидно, поскольку это работает, команду можно использовать в качестве основы для дополнения, чтобы она могла обрабатывать «foo» и «bar» в одной команде.

Если, конечно, это не на 100% невозможно — а вот после 4 дней попыток повторить 40 или 50 различных вариаций команды — я начинаю это подозревать!

Пожалуйста, если кто-нибудь ответит на это, опубликуйте команду пакетного файла, как у меня выше. Пожалуйста, не говорите мне переключиться на использование скриптов ps1 или давайте ответы, которые объясняют, что вводить в консольное окно.

Команду, которую я разместил выше, просто нужно немного изменить, чтобы можно было добавить «bar» к «foo», и тогда она будет обрабатывать более одной текстовой строки.

Причина, по которой это так сложно, кажется, в том, что если вы запускаете команду, чтобы удалить все строки, кроме тех, что содержат "foo", то вы уже удалили строки с "bar". Я подозреваю, что именно поэтому никто до сих пор не придумал работающего решения, а может быть, его просто нет.

Заранее спасибо всем, у кого есть работающий ответ. Обычно на такие вещи здесь отвечают очень быстро, или я просто продолжаю пробовать разные способы и у меня получается - но не в этот раз, это действительно сложно по какой-то причине.

решение1

Просто используйте два отдельных условия, соединенных оператором ИЛИ:

cat $_.FullName | ? { $_ -like '*foo*' -or $_ -like '*bar*' }

Скобки можно использовать для ясности, но они необязательны:

{ ($_ -like '*foo*') -or ($_ -like '*bar*') }

опубликуйте команду пакетного файла, как у меня выше. Пожалуйста, не говорите мне переключиться на использование скриптов ps1 или давайте ответы, которые объясняют, что вводить в консольное окно.

Это буквально одно и то же. Неважно, как вы вызываете скрипт PowerShell – сохраняете ли вы его в файле, передаете через командную строку или вводите с клавиатуры, это все равно скрипт PowerShell, и он следует тем же правилам синтаксиса.

решение2

Вместо этого вы можете использовать select-string, который принимает регулярные выражения:

gci *.txt | % { (cat $_.FullName | select-string -pattern 'foo|bar') | set-content $_.FullName -Force }

select-stringпозволяет вам в дальнейшем выполнять более сложное сопоставление регулярных выражений, если это необходимо.


Дальнейшее чтение

Связанный контент