grep в пакетном файле Windows

Я пытаюсь написать командный файл Windows, который будет просматривать определенный индексный файл html, который выглядит примерно так (упрощенно)

<a href=emergency.htm>Emergency Calls</a><br>
<a href=EmeRgency.htm>Emergency Calls</a><br>
<a href=Emergency.htm>Emergency Calls</a><br>
<a href=EMERGENCY.htm>Emergency Calls</a><br>
<a href=E911.htm>Emergency Calls</a><br>
<a href=e911.htm>Emergency Calls</a><br>

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

В unix работает следующее:

$ grep -v '^<a href=[^A-Z]*\.htm' helpindex.htm
<a href=EmeRgency.htm>Emergency Calls</a><br>
<a href=Emergency.htm>Emergency Calls</a><br>
<a href=EMERGENCY.htm>Emergency Calls</a><br>
<a href=E911.htm>Emergency Calls</a><br>

(-v отменяет совпадение)

Но используя UnxUtils grep под Windows, который является прямым портом unix grep, я не могу придумать способ цитирования регулярного выражения, которое работает. Это необходимо для использования в пакетном файле. Я пробовал ', "без радости, а также переключатель -E. Есть ли способ сделать это с помощью этого конкретного набора инструментов?

@janos привел меня к команде findstr в Windows, но она все еще не работает. Глядя на справку findstr, я вижу:

FINDSTR [/ B] [/ E] [/ L] [/ R] [/ S] [/ I] [/ X] [/ V] [/ N] [/ M] [/ O] [/ P] [ / F: файл] [/ C: строка] [/ G: файл] [/ D: список каталогов] [/ A: атрибуты цвета] [/ OFF [LINE]] строки [[диск:] [путь] имя файла [. ..]]

...
/ V Печатает только те строки, которые не содержат совпадений. ...
/ C: string Использует указанную строку как буквальную строку поиска. ...

Используйте пробелы для разделения нескольких строк поиска, если аргумент не имеет префикса / C. Например, "FINDSTR" hello there "x.y" выполняет поиск "hello" или "there" в файле x.y. 'FINDSTR / C: "hello there" x.y "ищет" hello there "в файле x.y.

Однако это тоже не работает:

C:\home\sftp>findstr /V  /C:"^<a href=[^A-Z]*\.htm" helpindex.htm
<a href=emergency.htm>Emergency Calls</a><br>
<a href=EmeRgency.htm>Emergency Calls</a><br>
<a href=Emergency.htm>Emergency Calls</a><br>
<a href=EMERGENCY.htm>Emergency Calls</a><br>
<a href=E911.htm>Emergency Calls</a><br>
<a href=e911.htm>Emergency Calls</a><br>

Либо findstr - это мусор, либо есть небольшое отличие от grep.


person Steve Cohen    schedule 27.09.2013    source источник
comment
У меня это работает в версии, поставляемой с Git Bash. Вы также можете попробовать собственные команды Windows find.exe и findstr.exe. Они похожи на grep (ничего общего с UNIX find)   -  person janos    schedule 27.09.2013
comment
найти регулярное выражение? Я этого не знал.   -  person Steve Cohen    schedule 27.09.2013
comment
Похоже, что findstr должен работать, но это не так: findstr / V '^ ‹a href = [^ A-Z] * \. htm' helpindex.htm выдает результаты mp, а не четыре строки, как uniz grep.   -  person Steve Cohen    schedule 27.09.2013
comment
У меня сейчас нет окон, чтобы проверить это, но одному из них нужны шаблоны, заключенные в двойные кавычки, даже если они выглядят ненужными, например "simpleterm". Не помню, было ли это find или findstr, следите за этим.   -  person janos    schedule 27.09.2013


Ответы (2)


У меня это отлично работает в командной консоли Windows:

grep -v "^<a href=[^A-Z]*\.htm" helpindex.htm

FINDSTR не работает с [^A-Z], потому что он использует нестандартную последовательность сортировки: см. Почему findstr не обрабатывает регистр должным образом (в некоторых случаях)?

Вы можете использовать FINDSTR, чтобы получить желаемый результат, используя:

findstr /rvc:"^<a href=[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]*\.htm" helpindex.htm

Параметр / C необходим, чтобы вся строка считалась одним поисковым запросом.

Параметр / R необходим для принудительной интерпретации поискового запроса как регулярного выражения. По умолчанию для параметра / C используется строковый литерал.

Возможно, вы захотите ознакомиться с Каковы недокументированные функции и ограничения команды Windows FINDSTR?. Есть длинный список "подводных камней"

Изменить

UnxUtils - это старый устаревший дистрибутив утилит GNU unix для Windows. Вы должны получить более новые выпуски от GNU Coreutils: см. Разница между UnxUtils и GNU CoreUtils

Я полагаю, что получил свой дистрибутив GNU Coreutils с http://gnuwin32.sourceforge.net/packages/coreutils.htm. Я не уверен, что это самый последний пакет, но он должен решить вашу проблему с grep. Он предоставляет удобный пакет многих утилит.

Другой вариант - получить отдельные утилиты GNU для Windows из http://gnuwin32.sourceforge.net/packages.html

person dbenham    schedule 27.09.2013
comment
grep у меня не работал. Вы используете версию unxutils? Но добавление ключа / R к findstr и расшифровка алфавита сделали. БЛАГОДАРНОСТЬ! - person Steve Cohen; 28.09.2013
comment
@SteveCohen - я использую GNU grep 2.5.1 для Windows - person dbenham; 28.09.2013
comment
Моя была 2.4.2 от UnxUtils - person Steve Cohen; 28.09.2013

Вы можете использовать мою программу FindRepl.bat, которая работает как хотите. Например:

> type helpindex.htm
<a href=emergency.htm>Emergency Calls</a><br>
<a href=EmeRgency.htm>Emergency Calls</a><br>
<a href=Emergency.htm>Emergency Calls</a><br>
<a href=EMERGENCY.htm>Emergency Calls</a><br>
<a href=E911.htm>Emergency Calls</a><br>
<a href=e911.htm>Emergency Calls</a><br>

> FindRepl /V "^<a href=[^A-Z]*\.htm" < helpindex.htm
<a href=EmeRgency.htm>Emergency Calls</a><br>
<a href=Emergency.htm>Emergency Calls</a><br>
<a href=EMERGENCY.htm>Emergency Calls</a><br>
<a href=E911.htm>Emergency Calls</a><br>

Вы можете загрузить FindRepl.bat с этого сайта

person Aacini    schedule 27.09.2013