От man find: Обратите внимание, что вы должны заключать в кавычки шаблоны как само собой разумеющееся, иначе оболочка будет расширять любые подстановочные знаки в них.
артданил
Ответы:
18
find -iname '*.xml'
В противном случае ваша оболочка расширяется *.xmlдо XYZ.xml, и фактически выполняемая команда
find -iname XYZ.xml
Причина, по которой он работает, если в текущем каталоге нет файлов XML, заключается в том, что оболочки обычно оставляют подстановочные знаки нерасширенными, если они не совпадают с чем-либо. В общем, в любое время вы хотите подстановочные быть расширен с помощью программы, отличной от оболочки (например , с помощью find, tar, scpи т.д.) , вы должны процитировать их так что оболочка не будет пытаться расширить их самостоятельно.
Thx, это так просто, но мне было интересно, как обойти это в течение нескольких месяцев. Я нашел это действительно странным и очень противоречивым поведением, но теперь я понимаю, так как это не находка, а ошибка Бэша.
Оливье Тупен,
2
Это не вина "bash" как таковая, а ваша отказ от цитирования подстановочных знаков, которые вы хотели передать в качестве аргументов. Это относится ко всем программам, которые принимают ввод оболочки. Оболочка расширяет их как глобусы, если они не указаны или не экранированы.
Калеб
1
Я думаю, что Оливье имел в виду это в том смысле, что это вопрос bash, а не о find.
пользователь неизвестен
6
Вы должны процитировать свой аргумент так:
find ./-name '*.xml'
так что он передается для поиска вместо раскрытия оболочкой, а затем передается для поиска в качестве расширенной версии.
Итак, если *.xmlв текущем каталоге ничего не совпадает, он передается буквально, поэтому он работает в другом случае. Очень полезный ответ.
Эрик Уилсон
1
Подстановочные знаки раскрываются оболочкой, а не командой. findэто одна из немногих команд, которая выполняет сопоставление с подстановочными знаками, аналогичное оболочке, в свое время.
При запуске ls *.xmlсначала оболочка расширяется *.xmlдо списка подходящих файлов, например file1.xmlfile2.xmlfile3.xml, а затем оболочка вызывает lsполученный список аргументов file1.xmlfile2.xmlfile3.xml. Вот почему вы видите тот же список имен файлов echo *.xml, даже если echoничего не знаете о файлах и не заботитесь о том, являются ли его аргументы именами файлов.
Когда вы бежите find . -name "*.xml":
Оболочка анализирует командную строку, чтобы распознать специальные символы и разбить ее на слова и выражения. Здесь есть только список слов find, ., -name, *.xmlгде *цитируются. Так *как цитируется, это обычный символ, что касается оболочки.
Оболочка запускает команду findс указанным списком аргументов: ., -name, *.xml.
findищет файлы, чье имя соответствует шаблону *.xmlв любом каталоге в текущем каталоге.
Когда вы запускаете find . -name *.xmlи нет подходящих файлов *.xml:
Оболочка анализирует командную строку, чтобы распознать специальные символы и разбить ее на слова и выражения. Здесь есть только список слов find, ., -name, *.xmlгде *не котируется.
Поскольку слово *.xmlсодержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла. Поскольку нет подходящих имен файлов, шаблон остается нерасширенным.
Оболочка выполняет команду findс результирующим списком аргументов, что ., -name, *.xml.
findищет файлы, чье имя соответствует шаблону *.xmlв любом каталоге в текущем каталоге.
Когда вы запускаете find . -name *.xmlи текущий каталог содержит file1.xml, file2.xmlи file3.xml:
Оболочка анализирует командную строку, чтобы распознать специальные символы и разбить ее на слова и выражения. Здесь есть только список слов find, ., -name, *.xmlгде *не котируется.
Поскольку слово *.xmlсодержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла: *.xmlзаменяется списком совпадающих имен файлов.
Оболочка выполняет команду findс результирующим списком аргументов, который ., -name, file1.xml, file2.xml, file3.xml.
findжалуется на синтаксическую ошибку при достижении file2.xml.
Когда вы запускаете find . -name *.xmlи текущий каталог содержит один соответствующий файл file.xml:
Оболочка анализирует командную строку, чтобы распознать специальные символы и разбить ее на слова и выражения. Здесь есть только список слов find, ., -name, *.xmlгде *не котируется.
Поскольку слово *.xmlсодержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла: *.xmlзаменяется списком совпадающих имен файлов.
Оболочка выполняет команду findс результирующим списком аргументов, что ., -name, file.xml.
findвидит совершенно правильную команду, но, вероятно, это не то, что вы намеревались: findвелено искать файлы, вызываемые file.xmlв любом каталоге, а не искать какие-либо подходящие файлы *.xml.
(Оценка и расширение оболочки имеет много других функций. Я упомянул только те, которые актуальны здесь.)
(То, что я описываю, это поведение по умолчанию большинства распространенных оболочек: sh, bash, dash, ksh, ... Некоторые оболочки могут быть настроены для отображения ошибки вместо запуска команды с нерасширенными подстановочными знаками или для расширения несоответствующих подстановочных знаков до пустых список. Ни один из них не поможет здесь.)
Это не работает, когда глобус соответствует чему-либо в текущем каталоге. Это неправильный синтаксис! *Всегда должны быть заключены в кавычки или спасшийся передать его найти.
man find
: Обратите внимание, что вы должны заключать в кавычки шаблоны как само собой разумеющееся, иначе оболочка будет расширять любые подстановочные знаки в них.Ответы:
В противном случае ваша оболочка расширяется
*.xml
доXYZ.xml
, и фактически выполняемая командаПричина, по которой он работает, если в текущем каталоге нет файлов XML, заключается в том, что оболочки обычно оставляют подстановочные знаки нерасширенными, если они не совпадают с чем-либо. В общем, в любое время вы хотите подстановочные быть расширен с помощью программы, отличной от оболочки (например , с помощью
find
,tar
,scp
и т.д.) , вы должны процитировать их так что оболочка не будет пытаться расширить их самостоятельно.источник
bash
, а не оfind
.Вы должны процитировать свой аргумент так:
так что он передается для поиска вместо раскрытия оболочкой, а затем передается для поиска в качестве расширенной версии.
источник
*.xml
в текущем каталоге ничего не совпадает, он передается буквально, поэтому он работает в другом случае. Очень полезный ответ.Подстановочные знаки раскрываются оболочкой, а не командой.
find
это одна из немногих команд, которая выполняет сопоставление с подстановочными знаками, аналогичное оболочке, в свое время.При запуске
ls *.xml
сначала оболочка расширяется*.xml
до списка подходящих файлов, напримерfile1.xml
file2.xml
file3.xml
, а затем оболочка вызываетls
полученный список аргументовfile1.xml
file2.xml
file3.xml
. Вот почему вы видите тот же список имен файловecho *.xml
, даже еслиecho
ничего не знаете о файлах и не заботитесь о том, являются ли его аргументы именами файлов.Когда вы бежите
find . -name "*.xml"
:find
,.
,-name
,*.xml
где*
цитируются. Так*
как цитируется, это обычный символ, что касается оболочки.find
с указанным списком аргументов:.
,-name
,*.xml
.find
ищет файлы, чье имя соответствует шаблону*.xml
в любом каталоге в текущем каталоге.Когда вы запускаете
find . -name *.xml
и нет подходящих файлов*.xml
:find
,.
,-name
,*.xml
где*
не котируется.*.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла. Поскольку нет подходящих имен файлов, шаблон остается нерасширенным.find
с результирующим списком аргументов, что.
,-name
,*.xml
.find
ищет файлы, чье имя соответствует шаблону*.xml
в любом каталоге в текущем каталоге.Когда вы запускаете
find . -name *.xml
и текущий каталог содержитfile1.xml
,file2.xml
иfile3.xml
:find
,.
,-name
,*.xml
где*
не котируется.*.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла:*.xml
заменяется списком совпадающих имен файлов.find
с результирующим списком аргументов, который.
,-name
,file1.xml
,file2.xml
,file3.xml
.find
жалуется на синтаксическую ошибку при достиженииfile2.xml
.Когда вы запускаете
find . -name *.xml
и текущий каталог содержит один соответствующий файлfile.xml
:find
,.
,-name
,*.xml
где*
не котируется.*.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла:*.xml
заменяется списком совпадающих имен файлов.find
с результирующим списком аргументов, что.
,-name
,file.xml
.find
видит совершенно правильную команду, но, вероятно, это не то, что вы намеревались:find
велено искать файлы, вызываемыеfile.xml
в любом каталоге, а не искать какие-либо подходящие файлы*.xml
.(Оценка и расширение оболочки имеет много других функций. Я упомянул только те, которые актуальны здесь.)
(То, что я описываю, это поведение по умолчанию большинства распространенных оболочек: sh, bash, dash, ksh, ... Некоторые оболочки могут быть настроены для отображения ошибки вместо запуска команды с нерасширенными подстановочными знаками или для расширения несоответствующих подстановочных знаков до пустых список. Ни один из них не поможет здесь.)
источник
Это работает на Solaris 10:
find /directory-to-search/* -prune -name "*gz"
источник
.xml
.Пожалуйста, попробуй:
источник
*
Всегда должны быть заключены в кавычки или спасшийся передать его найти.