найти ближайшую папку соответствия

Я только что снова столкнулся с этим вариантом использования; Я кратко расскажу, как я с этим справился.

Я хотел загрузить (но не установить) Git и PostgreSQL, а затем установить их во время процесса бродячей подготовки.

Я использовал следующую команду со свежей виртуальной машины, чтобы загрузить пакеты со всеми зависимостями (после sudo mkdir / vagrant / packages ):

sudo yumdownloader --destdir=/vagrant/packages/ --resolve -y git postgresql

Уловка с этой командой в том, что она загружает слишком много . Следующим шагом было установить RPM, которые мне на самом деле были необходимы для установки. Я сделал это, попробовав:

sudo yum install /vagrant/packages/git-1.7.1-4.el6_7.1.x86_64.rpm /vagrant/packages/postgresql-8.4.20-6.el6.x86_64.rpm

И нажав «Нет» в запросе подтверждения, потому что я мог видеть, что он планирует загрузку зависимостей. Я взял перечисленные зависимости и добавил их в свою команду:

sudo yum install /vagrant/packages/git-1.7.1-4.el6_7.1.x86_64.rpm /vagrant/packages/postgresql-8.4.20-6.el6.x86_64.rpm /vagrant/packages/perl-* /vagrant/packages/postgresql-libs-8.4.20-6.el6.x86_64.rpm

Это будет успешно работать без загрузки, поэтому я запустил:

cd /vagrant/packages/
mkdir save
mv /vagrant/packages/git-1.7.1-4.el6_7.1.x86_64.rpm /vagrant/packages/postgresql-8.4.20-6.el6.x86_64.rpm /vagrant/packages/perl-* /vagrant/packages/postgresql-libs-8.4.20-6.el6.x86_64.rpm save/
rm *.rpm
mv save/* .
rmdir save

Результат: каталог "packages" с только действительно необходимыми зависимостями из свежего изображения Vagrant.

Затем, добавив команду подготовки оболочки к моему Vagrantfile :

  config.vm.provision "shell", inline: <<-SHELL
    yum install -C -y /vagrant/packages/*
  SHELL

... У меня установлены Git и PostgreSQL, которые готовы к использованию после любого бродяг , даже если vagrant destroy был запущен.

4
15.08.2019, 22:34
2 ответа

Эта функция bash выполняет перебор -принудительно findпо всем уровням каталогов под текущим каталогом в поисках именованного каталога.

cdd() {
  if [ "$#" -ne 1 ]
  then
    printf '%s: Error: one directory name expected\n' "${FUNCNAME[0]}" >&2
    return
  fi

  maxdepth=$(find. -type d -exec sh -c 'printf %s "$1" | LC_ALL=C tr -dc / | wc -c' findshell {} \; | sort -n | tail -1)
  for((i=1; i <= maxdepth; i++))
  do
    dir=$(find. -mindepth "$i" -maxdepth "$i" -type d -name "$1")
    if [ -n "$dir" ]
    then
        command cd -- "$dir"
        return
    fi
  done
  printf '%s: %s: no such directory found\n' "${FUNCNAME[0]}" "$1" >&2
}

Первая команда findвыполняет фрагмент оболочки для каждого каталога в текущем каталоге; фрагмент оболочки выводит имя каталога в конвейер trи wc, который удаляет каждый символ, не являющийся косой чертой -, а затем подсчитывает количество косых черт -. Я перенял этот трюк у ilkkachu и Stéphane Chazelas здесь . После вывода всех глубин каталога мы sort | tailнаходим наибольшее число. Это число является максимальной глубиной каталога, в которой нам нужно искать.

После этого выполняется цикл по find, ограниченный точно каждой глубиной каталога по очереди, начиная с текущего каталога до самого глубокого каталога. Если совпадение найдено, мы cdи выходим из функции. Если совпадений не найдено, мы выходим из цикла и выводим сообщение в stderr.

1
27.01.2020, 21:03

С помощью zshможно сделать:

cdd() cd -- **/$1(/Od[1])

cdd themes

Эта функция cddнаходит все файлы типа каталога(/)с именем, заданным в качестве аргумента ($1), Oупорядочивает их по depth и выбирает первый([1]).

Не очень эффективным является то, что он сканирует все дерево каталогов (, пропуская скрытые каталоги, добавьте квалификатор Dglob, чтобы изменить это ), даже если в текущем каталоге есть соответствующий каталог.

Чтобы пройти по дереву каталогов на один уровень глубины за раз, вы можете вместо этого:

cdd() {
  local dirs matches
  dirs=(.)
  while (($#dirs)) {
    matches=($^dirs/$1(N/[1]))
    if (($#matches)) {
      cd $matches[1]
      return
    }
    dirs=($^dirs/*(/N))
  }
  print >&2 Not found
  return 1
}
3
27.01.2020, 21:03

Теги

Похожие вопросы