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.