Gnuwin32 find.exe расширяет подстановочный знак перед выполнением поиска
Я использую двоичные файлы Gnuwin32 в среде Windows.
Когда я хочу найти файлы определенного типа, скажем, PDF, я обычно запускаю:
find . -iname '*.pdf' -print
Это отлично работает в любой UNIX-системе.
find.exe . -iname "*.pdf" -print
Но под Windows, заменив одинарные кавычки двойными кавычками, он работает только тогда, когда в текущем каталоге нет файла PDF, в противном случае расширяется *
.
Хуже: когда в текущем каталоге есть ровно один файл PDF, он будет расширяться, не будет синтаксической ошибки, и вы получите неправильные результаты.
Я попытался выйти из *
с помощью каретки, обратной косой черты, самой звезды, вставив двойные кавычки: ничего не работает для меня.
Реальный пример:
Хорошо, вот все мои файлы:
C:\tmp>find . -type f
./a/1.pdf
./a/2.pdf
./a/aa/1.pdf
./b/1.pdf
./b/bb/1.pdf
./b/bb/2.pdf
Хорошее поведение, подстановочный знак не был расширен
C:\tmp>find . -iname "*.pdf"
./a/1.pdf
./a/2.pdf
./a/aa/1.pdf
./b/1.pdf
./b/bb/1.pdf
./b/bb/2.pdf
C:\tmp>cd a
Осторожно, несовместимое поведение, подстановочные знаки были расширены:
C:\tmp\a>find . -iname "*.pdf"
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
C:tmp\a>cd ..\b
Осторожно, несовместимое поведение, подстановочные знаки были расширены:
C:\tmp\b>find . -iname "*.pdf"
./1.pdf
./bb/1.pdf
Спасибо
Ответы
Ответ 1
Я нашел решение своей проблемы.
- Gnuwin32
find.exe
не работает в последних версиях Windows (Vista, Seven), потому что он расширяет подстановочные знаки, соответствующие только содержимому текущего каталога.
- Аналогично, старая версия find.exe из UnxUtils понесла ту же ошибку.
- Работает последняя
find.exe
из UnxUtils.
Ответ 2
Одним из способов является добавление шаблона/расширения, который оболочка Windows не расширяет, но поиск GNU делает:
find.exe . -name *[.:]pdf -print
Оболочка Windows [*] не интерпретирует и не расширяет квадратные скобки. Кроме того, двоеточие не является допустимым символом в именах файлов Windows, поэтому этот шаблон не может соответствовать имени файла Windows, и оболочка Windows всегда будет передавать шаблон через find.exe.
Find.exe найдет файлы, заканчивающиеся на .pdf
или :pdf
, но поскольку ни одно из файлов не может иметь имя, заканчивающееся на :pdf
под Windows, оно будет находить файлы, заканчивающиеся на .pdf
.
[*] На самом деле это C-среда выполнения, которая выполняет/не выполняет эти разблокировки. Я не очень хорошо разбираюсь в среде исполнения Win32 C, чтобы уточнить различие, поэтому пока для этого обходного пути я просто говорю "shell".
Ответ 3
У меня была эта проблема сегодня днем.
Benoit UnxUtils может работать.
Я также нашел, что MinGW find.exe может работать, он находится под моим
"MinGW\MSYS\1.0\Bin"
Каталог. И это согласуется с руководством.
gnuwin32 и UnxUtils: find.exe . -name GameCli*
работают, но find.exe . -name 'GameCli*'
не работает.
MinGW find.exe . -name 'GameCli*'
работает.
Ответ 4
Я не нашел ничего лучше, чем просто избегать подстановочных знаков
find.exe . -iregex ".+\.pdf" -print
Ответ 5
@OP, у меня последовательное поведение
C:\test\temp>find . -iname "*.txt"
./1.txt
./2.txt
C:\test\temp>cd a
C:\test\temp\a>find . -iname "*.txt"
C:\test\temp\a>cd ..\b
C:\test\temp\b>find . -iname "*.txt"
C:\test\temp\b>find --version
GNU find version 4.2.20
Features enabled: CACHE_IDS D_TYPE
Возможно, вы захотите использовать findutils вместо UnxUtils.