Трубопроводный выход Findstr - PullRequest
1 голос
/ 29 апреля 2010

Командная строка Windows, я хочу найти в файле все строки, начинающиеся с:

# NNN "<file>.inc"

, где NNN - это число, а <file> - любая строка.

Я хочу использовать findstr, потому что не могу требовать, чтобы пользователи сценария установили ack.

Вот выражение, которое я придумал:

>findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9_]*.inc" all_pre.txt

Файл для поиска all_pre.txt.

Пока все хорошо. Теперь я хочу передать это другой команде, например, more.

>findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9]*.inc" all_pre.txt | more

Результатом этого будет тот же вывод, что и в предыдущей команде, но с именем файла в качестве префикса для каждой строки (all_pre.txt).

Затем приходит:

FINDSTR: cannot open |
FINDSTR: cannot open more

Почему труба не работает?


фрагмент содержимого all_pre.txt

# 1 "main.ss"
# 7 "main.ss"
# 11 "main.ss"
# 52 "main.ss"
# 1 "Build_flags.inc"
# 7 "Build_flags.inc"
# 11 "Build_flags.inc"    
# 20 "Build_flags.inc"
# 45 "Build_flags.inc(function a called from b)"

РЕДАКТИРОВАТЬ: Мне нужно также избежать точки в регулярном выражении. Не проблема, но стоит упомянуть.

>findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9_]*\.inc" all_pre.txt

РЕДАКТИРОВАТЬ после Фрэнка Боллака:

>findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9_]*\.inc.*" all_pre.txt | more

не работает, хотя (я думаю) он должен искать ту же строку, что и раньше, затем любой символ любое количество раз. Это должно включать ", верно?

Ответы [ 3 ]

3 голосов
/ 29 апреля 2010

В вашем поисковом шаблоне отсутствует трейлинг \".

findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9]*.inc\"" all_pre.txt | more

Вышеуказанное работает для меня.

Edit:

findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9]*\.inc.*\"" all_pre.txt | more

Эта обновленная строка поиска теперь будет соответствовать этим строкам из вашего примера:

# 1 "Build_flags.inc"
# 7 "Build_flags.inc"
# 11 "Build_flags.inc"
# 20 "Build_flags.inc"
# 45 "Build_flags.inc(function a called from b)"

Edit:

Чтобы обойти эту «ошибку» в findstr, вы можете поместить свой поиск в командный файл, например так:

@findstr /r /c:"^# [0-9][0-9]* \"[a-zA-Z0-9_]*\.inc" %1

Назовите это как-то myfindstr.bat и назовите так:

myfinsdtr all_pre.txt | more

Теперь вы можете использовать операторы pipe и перенаправления как обычно.

Надеюсь, это поможет.

1 голос
/ 03 июня 2013

Я не могу действительно объяснить, почему, но из моего опыта, хотя findstr поведение с фиксированными строками (например, /c:"some string") в точности соответствует желаемому, регулярные выражения - это другой зверь. Я обычно использую функцию поиска по фиксированным строкам, например, для извлечения строк из CSV-файлов:

C:\> findstr /C:"literal string" filename.csv >  output.csv

Нет проблем.

Но использование регулярных выражений (например, /R "^\"some string\""), по-видимому, приводит к выводу вывода findstr на консоль и не может быть перенаправлено любым способом. Я попытался >, >>, 1>, 2> и все не удалось при использовании регулярных выражений. Мой обходной путь для этого заключается в использовании findstr в качестве вторичной команды. В моем случае я сделал это:

C:\> type filename.csv | findstr /R "^\"some string\"" > output.csv

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

Я подтвердил, что поведение одинаково как в Windows 2008, так и в Windows 7.

РЕДАКТИРОВАТЬ: Другой вариант также, очевидно, работает:

C:\> findstr /R "^\"some string\"" < filename.csv > output.csv

это тот же принцип, что и при использовании type, но только при использовании самой командной строки для создания канала.

0 голосов
/ 22 марта 2018

Если вы используете регулярное выражение с четным числом двойных кавычек, оно отлично работает. Но число символов "нечетное, перенаправление не работает. Вы можете либо завершить свое регулярное выражение второй кавычкой (вы можете использовать диапазон для этой цели: [\"\"]), либо заменить свой символ кавычки метасимволом точки.

Похоже, проблема cmd.exe, findstr не виноват.

...