Проверьте, существует ли хотя бы один каталог с префиксом имени в bash - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть скрипт с именем, введенным пользователем, и я хочу определить, существуют ли какие-либо каталоги, начиная с этого имени.

Этот код выглядит следующим образом:

runTest() {
  if test -d "$name"*; then
    echo "Directories starting with $name already exist"
  fi
}

Работает нормальноесли существует только один такой каталог:

name=foobar
rm -rf foobar*
mkdir foobar1
runTest # now the code will work

... но он не работает, если есть несколько совпадений:

name=foobar
rm -rf foobar*
mkdir foobar1 foobar2
runTest # now the code will emit an error: "test: too many arguments"

Как я могусделать эту работу с любым количеством каталогов, не предполагая, что одно из совпадений всегда будет включать определенное число (например, 1)?

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Попробуйте это.

#! /bin/bash -e
name='foobar'

if [ `find . -maxdepth 1 -type d -name "$name*" -print -quit` -gt 1 ]; then
  echo "Directories starting with $name already exist"
fi
0 голосов
/ 04 декабря 2018

Самое простое решение:

ls "$name"*/ >/dev/null 2>&1 && echo "Directories starting with $name already exist"

(осторожно: может не работать в некоторых особых случаях (специальные символы в именах файлов и т. Д.))

0 голосов
/ 04 декабря 2018

В качестве примера работающей (только для bash - не /bin/sh совместимой) альтернативы рассмотрим:

if dirs=( "$name"*/ ) && [[ -d ${dirs[0]} ]]; then
  echo "Directories starting with $name already exist"
fi
  • Назначение массива работает с любым количеством совпадений
  • ... но первая запись в массиве будет действительным каталогом только в том случае, если глоб успешно расширился (а завершающий / в выражении глобуса не позволяет ему расширяться во все , кроме каталогов, поэтомуесли у результата вообще есть какие-либо каталоги, вы знаете, что все элементы, в которые он был расширен, являются каталогами).

Если вам нужно что-то, что работает для /bin/sh какхорошо, рассмотрим следующую функцию:

directoriesExist() { [ -d "$1" ]; }
if directoriesExist "$name"*/;  then
  echo "Directories starting with $name already exist"
fi

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


Потому что [ - это встроенная оболочка, эти подходы, основанные на глобальных вычислениях, имеют гораздо меньшие затраты на постоянные коэффициенты, чем подходы, зависящие от внешних инструментов, что сделает их значительно более быстрыми.ll (за исключением некоторых угловых случаев, таких как каталоги, настолько большие, что предпочтительно останавливаться после того, как найдено первое совпадение;где find . -name "$name*" -print -quit может быть полезно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...