В состоянии Bash if, как проверить, существуют ли какие-либо файлы, соответствующие простому шаблону?

Глупо, я использовал такое условие как часть скрипта:

if [ $(ls FOO* 2> /dev/null) ] # if files named "FOO*" were downloaded then echo "Files found" # ... process and email results else echo "Not found" # ... email warning that no files were found (against expectations) fi 

Это работает для нулевого и одного файла с именем FOO* , но сбой, если их больше одного . Из журналов я обнаружил несколько различных сообщений об ошибках, вытекающих из этого:

 [: FOO_20131107_082920: unary operator expected [: FOO_20131108_070203: binary operator expected [: too many arguments 

Мой вопрос: каков правильный способ проверки в if Bash if , существует ли один или несколько файлов, чье имя начинается с FOO ?

GNU bash, версия 4.2.25 (1) -release (x86_64-pc-linux-gnu)

3 Solutions collect form web for “В состоянии Bash if, как проверить, существуют ли какие-либо файлы, соответствующие простому шаблону?”

Это происходит потому, что ваша подстановка команды для ls выводит пробелы, и в конечном итоге она претерпевает расщепление слов перед передачей в [ . Менее прочным способом было бы поместить файлы в массив, а затем проверить, что в массиве есть хотя бы один член.

 shopt -s nullglob files=( FOO* ) if (( ${#files[@]} )); then # there were files fi 

Это работает потому, что (( по умолчанию возвращает true, если значение не равно 0, а ${#files[@]} получает количество элементов в массиве (которое будет> 0, если есть файлы, соответствующие glob).

Вы также можете сделать что-то подобное, если nullglob не установлен:

 if ls FOO* >/dev/null 2>&1; then # there were files fi 

Это просто проверяет код выхода ls , который будет равен 1, если вы передали имя файла, которого не существует (буква FOO* , если ничего не сопоставлено (если, конечно, вы не злы и есть файл с именем FOO* , и в этом случае он вернет 0 :-))).

Обратите внимание, что оба они также соответствуют каталогам. Если вы действительно хотите сопоставлять обычные файлы, вам необходимо проверить, что:

 for file in FOO*; do if [[ -f $file ]]; then # file found, do some stuff and break break fi done 

Многострочные ответы выше не соответствовали моему желанию однострочного решения и не изменяли окружающую среду. Вот общий однострочный вкладыш, который может работать на вас:

 echo $(ls FOO* 2>/dev/null | wc -w) 

/ dev / null – это потому, что ls выдает ошибку, если нет файла. Это просто игнорирует ls и подсчитывает количество найденных файлов на основе количества «слов» (действительно имен файлов). Вы можете использовать его в простой инструкции if:

 if [ 0 -lt $(ls FOO* 2>/dev/null | wc -w) ]; then echo "Some FOO is there." fi 

Этот подход имеет гибкость не только проверки наличия каких-либо совпадающих файлов, но и опциональной проверки того, сколько совпадающих файлов существует (просто измените 0 и / или -lt ), а затем продолжайте дальше.

Я не проверял файлы / папки, в которых есть подстановочные знаки или пробелы; Я подозреваю, что вышеупомянутый метод дал бы неправильный подсчет пробелов в частности, что является лишь проблемой, если требуется точный подсчет за пределами 0. Одно исправление, которое я пробовал для этого, – использовать $(ls -l FOO* 2>/dev/null | wc -l) , который разбивает список вниз по строкам и поэтому должен принимать больше белого.

Существует еще один вариант, используя случай ,

 FILES=FOO* FILES=$(echo $FILES) case $FILES in FOO\*) echo "Not found" ;; esac 

Это работает как случай, ожидающий проверки только одного аргумента.

  • Почему `ls` перечисляет следующие файлы в, казалось бы, разных порядках?
  • Список файлов с момента времени X до времени Y
  • Команда ls без (скрытия) даты и времени
  • Как раскрыть скрытые файлы в списках файлов `ls`?
  • Соответствие шаблону ls
  • Почему * не * разбирать `ls`?
  • Файл не отображается с помощью vi, но отображается с помощью команды ls -l CD *
  • Замена команды in for loop не работает
  • Как отключить мигание имен файлов в rlogin
  • значение капитала S в длинном выпуске
  • передача переменной ls в grep при выполнении поиска файла работает только внутри каталога
  • Interesting Posts

    Можно ли читать PVclock из пользовательского пространства?

    Всегда ли необходимо запускать команды etckeeper git с помощью команды vcs?

    Отформатируйте вывод cputime для ps

    «В этой системе переменные EFI не поддерживаются»

    Исправьте настройки файла ssh для туннеля на третий компьютер

    Есть ли способ сделать apt-отчет, какие пакеты в dist-upgrade будут использовать дополнительное дисковое пространство?

    Переименовать команду для удаления подстроки

    Есть ли соглашение для добавления файлов .pc для pkg-config?

    Автоматизация задач на веб-сайте на безголовом сервере

    Какие аппаратные компоненты не требуют драйвера и почему

    Как проверить apt-репозиторий?

    Dell XPS 15 работает на Linux

    `du` получить разные результаты на разных машинах для одной и той же папки

    Командная строка 7z добавляет файл в плоский каталог 7z-файл

    После обновления и обновления apt-get мне нужно перекомпилировать и переустановить программное обеспечение, которое я не установил с помощью apt-get install?

    Linux и Unix - лучшая ОС в мире.