Привет, Томас, как насчет того, чтобы добавить лучшее решение вопроса вместо простого отрицательного голоса.
JeremyWeir
8
Также Томас, ваш пример того, почему не использовать его, использует ls -l, мой ответ используетls -1
JeremyWeir
10
И этот ответ не анализирует вывод, он просто подсчитывает выводимые строки, и я почти уверен, что даже если в имени файла есть странные символы, ls -1он будет печатать одну строку для каждого файла
JeremyWeir
2
Подсчет строк - это разбор. И он вернет неправильное число, если какие-либо файлы содержат \n(и да, это действительно в именах файлов).
Марсельм
1
Скажите, пожалуйста, какой магический символ должен быть в имени файла, чтобы счетчик строк был нулевым?
Это хорошо, потому что вы действительно можете что- то сделать с файлами после того, как их найдете.
ephsmith
+1 для заключения подоболочки с командой find в скобки, чтобы сделать myarray переменной массива. В противном случае, если find не вернет результат, ${#myarray[@]}равный 1
shaffooo
также можно упростить, используя ls -1 *.pyвместо find
JrBenito
Если в имени любого из файлов есть пробел, то один экземпляр будет засчитан как два.
Джон Гриффит
16
При этом используется ls (1), если файлов flac не существует, ls сообщает об ошибке, и сценарий завершается; в противном случае сценарий продолжается, и файлы могут быть обработаны
#! /bin/sh
ls *.flac >/dev/null || exit## Do something with flac files here
Вы должны быть осторожны, какой флаг вы добавляете в свое ifутверждение и как он соотносится с желаемым результатом.
Если вы хотите проверять только обычные файлы, а не другие типы записей файловой системы, вам нужно изменить скелет кода на:
if [ -f file ]; thenechotrue;
fi
Использование -fограничивается ifобычными файлами, тогда как -eоно более обширное и соответствует всем типам записей файловой системы. Конечно, есть и другие варианты, такие как -dкаталоги и т. Д. См. Http://tldp.org/LDP/abs/html/fto.html для хорошего списка.
Как указано в @msw, test(т.е. [) задохнется, если вы попытаетесь передать ему более одного аргумента. Это может произойти в вашем случае, если glob for *.flacвернул более одного файла. В этом случае попробуйте обернуть ifтест в цикл, например:
for file in ./*.pdf
doif [ -f "${file}" ]; thenecho'true';
breakfidone
Таким образом, вы выберете breakпервый экземпляр нужного вам расширения файла и сможете продолжить работу с остальной частью скрипта.
except test(aka [) жалуется, если шаблон расширяется до более чем одного файла: «ожидается бинарный оператор» или «слишком много аргументов»
msw
1
@msw - спасибо, даже не подумал об этой проблеме. Я попытался изменить свой ответ, чтобы учесть это.
dtlussier
Вы должны заключить переменную в кавычки, т.е. использовать "$file", потому что имя файла может содержать некоторые неправильные символы, такие как пробелы или звездочки.
Роман Чепляка 04
3
#!/bin/bash
files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l)
if [ "$files" != "0" ]
thenecho"Some files exists."elseecho"No files with that extension."fi
Это работает, но вы закапываете lede - причина, по которой он работает, заключается в том, что одинарная скобка [(в отличие от более распространенной [[) не предотвращает подстановку.
Адриан Петреску,
2
shopt -s nullglob
set -- $(echo *.ext)
if [ "${#}" -gt 0 ];thenecho"got file"fi
Это не правильно. Во-первых, вы, вероятно, имели в виду -geвместо -gt, потому что иначе ваш код не обнаружит один файл. Во-вторых, если нет файлов, соответствующих шаблону, любая соответствующая оболочка оставит строку *.extнетронутой, так что вы все равно получите один «результат».
Роман Чепляка 04
$ # - это 1 для одного файла и 0 для файлов без файлов.
frayser
1
только bash:
any_with_ext () (
ext="$1"
any=falseshopt -s nullglob
for f in *."$ext"; do
any=truebreakdoneecho$any
)
if $( any_with_ext flac ); thenecho"have some flac"elseecho"dir is flac-free"fi
Я использую круглые скобки вместо фигурных скобок, чтобы гарантировать, что используется подоболочка (не хочу, чтобы ваши текущие nullglobнастройки были искажены ).
Функция have_anyиспользует $#для подсчета своих аргументов, а [ $# -gt 0 ]затем проверяет, есть ли хотя бы один аргумент. Использование ./*.flacвместо вместо простого *.flacвызова to have_anyпозволяет избежать проблем, вызванных файлами с такими именами, как --help.
Это указано в конце раздела « Условные выражения » в руководстве по zsh. Поскольку [[отключает подстановку имени файла, нам нужно принудительно генерировать имя файла, используя (#q)в конце строки подстановки, затем Nфлаг ( NULL_GLOBпараметр), чтобы сгенерированная строка была пустой в случае отсутствия совпадения.
if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi
Как видите, это всего лишь одна строка кода, но она работает достаточно хорошо. Он должен работать как с bash, так и с posix-совместимой оболочкой, такой как dash. Он также нечувствителен к регистру и не заботится о том, какие типы файлов (обычные, символические ссылки, каталоги и т. Д.) Присутствуют, что может быть полезно, если у вас есть некоторые символические ссылки или что-то в этом роде.
ls -l
, мой ответ используетls -1
ls -1
он будет печатать одну строку для каждого файла\n
(и да, это действительно в именах файлов).#/bin/bash myarray=(`find ./ -maxdepth 1 -name "*.py"`) if [ ${#myarray[@]} -gt 0 ]; then echo true else echo false fi
источник
${#myarray[@]}
равный 1ls -1 *.py
вместо findПри этом используется ls (1), если файлов flac не существует, ls сообщает об ошибке, и сценарий завершается; в противном случае сценарий продолжается, и файлы могут быть обработаны
#! /bin/sh ls *.flac >/dev/null || exit ## Do something with flac files here
источник
if ls *.flac >/dev/null 2>&1; then ... fi;
shopt -s nullglob if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ] then echo true fi
источник
Вы должны быть осторожны, какой флаг вы добавляете в свое
if
утверждение и как он соотносится с желаемым результатом.Если вы хотите проверять только обычные файлы, а не другие типы записей файловой системы, вам нужно изменить скелет кода на:
if [ -f file ]; then echo true; fi
Использование
-f
ограничиваетсяif
обычными файлами, тогда как-e
оно более обширное и соответствует всем типам записей файловой системы. Конечно, есть и другие варианты, такие как-d
каталоги и т. Д. См. Http://tldp.org/LDP/abs/html/fto.html для хорошего списка.Как указано в @msw,
test
(т.е.[
) задохнется, если вы попытаетесь передать ему более одного аргумента. Это может произойти в вашем случае, если glob for*.flac
вернул более одного файла. В этом случае попробуйте обернутьif
тест в цикл, например:for file in ./*.pdf do if [ -f "${file}" ]; then echo 'true'; break fi done
Таким образом, вы выберете
break
первый экземпляр нужного вам расширения файла и сможете продолжить работу с остальной частью скрипта.источник
test
(aka[
) жалуется, если шаблон расширяется до более чем одного файла: «ожидается бинарный оператор» или «слишком много аргументов»"$file"
, потому что имя файла может содержать некоторые неправильные символы, такие как пробелы или звездочки.#!/bin/bash files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l) if [ "$files" != "0" ] then echo "Some files exists." else echo "No files with that extension." fi
источник
Лучшее решение
(if [ -e *.flac ];)
не сработало для меня, дав:[: too many arguments
if ls *.flac >/dev/null 2>&1;
тогда это будет работать.источник
Вы можете использовать -f, чтобы проверить, существуют ли файлы определенного типа:
#!/bin/bash if [ -f *.flac ] ; then echo true fi
источник
[
(в отличие от более распространенной[[
) не предотвращает подстановку.shopt -s nullglob set -- $(echo *.ext) if [ "${#}" -gt 0 ];then echo "got file" fi
источник
-ge
вместо-gt
, потому что иначе ваш код не обнаружит один файл. Во-вторых, если нет файлов, соответствующих шаблону, любая соответствующая оболочка оставит строку*.ext
нетронутой, так что вы все равно получите один «результат».только bash:
any_with_ext () ( ext="$1" any=false shopt -s nullglob for f in *."$ext"; do any=true break done echo $any ) if $( any_with_ext flac ); then echo "have some flac" else echo "dir is flac-free" fi
Я использую круглые скобки вместо фигурных скобок, чтобы гарантировать, что используется подоболочка (не хочу, чтобы ваши текущие
nullglob
настройки были искажены ).источник
Вот решение, в котором не используются внешние команды (т.е. нет
ls
), а вместо этого используется функция оболочки. Протестировано в bash:shopt -s nullglob function have_any() { [ $# -gt 0 ] } if have_any ./*.flac; then echo true fi
Функция
have_any
использует$#
для подсчета своих аргументов, а[ $# -gt 0 ]
затем проверяет, есть ли хотя бы один аргумент. Использование./*.flac
вместо вместо простого*.flac
вызова tohave_any
позволяет избежать проблем, вызванных файлами с такими именами, как--help
.источник
Для завершения с помощью zsh:
if [[ -n *.flac(#qN) ]]; then echo true fi
Это указано в конце раздела « Условные выражения » в руководстве по zsh. Поскольку
[[
отключает подстановку имени файла, нам нужно принудительно генерировать имя файла, используя(#q)
в конце строки подстановки, затемN
флаг (NULL_GLOB
параметр), чтобы сгенерированная строка была пустой в случае отсутствия совпадения.источник
Вот довольно простое решение:
if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi
Как видите, это всего лишь одна строка кода, но она работает достаточно хорошо. Он должен работать как с bash, так и с posix-совместимой оболочкой, такой как dash. Он также нечувствителен к регистру и не заботится о том, какие типы файлов (обычные, символические ссылки, каталоги и т. Д.) Присутствуют, что может быть полезно, если у вас есть некоторые символические ссылки или что-то в этом роде.
источник
Я пробовал это:
if [ -f *.html ]; then echo "html files exist" else echo "html files dont exist" fi
Я без проблем использовал этот фрагмент кода для других файлов, но для файлов html получил ошибку :
Затем я попробовал решение подсчета @ JeremyWeir, которое сработало для меня.
Имейте в виду, что вам придется сбросить счетчик, если вы делаете это в цикле:
count=$((0))
источник
Это должно работать в любой подобной оболочке:
if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then echo true fi
Это также работает с GNU
find
, но IDK, если он совместим с другими реализациямиfind
:if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then echo true fi
источник