Найти каталог внутри подкаталога с помощью терминала macOS

Скопировано изhttps://unix.stackexchange.com/a/88327

Предположим, что ваш /bin/shявляется POSIXsh(на Solaris 10 и более ранних версиях, в котором вместо этого была оболочка Bourne, вместо этого используйте /usr/xpg4/bin/sh):

if [ -t 0 ] && [ -t 1 ]; then
  old_settings=$(stty -g) || exit
  stty -icanon -echo min 0 time 3 || exit
  printf '\033[6n'
  pos=$(dd count=1 2> /dev/null)
  pos=${pos%R*}
  pos=${pos##*\[}
  x=${pos##*;} y=${pos%%;*}
  stty "$old_settings"
fi

Это предполагает, что весь ответ придет за один раз, ожидая его до 0,3 секунды. В целом это должно быть верно для эмуляторов терминала и устройств pty, но не обязательно для терминалов через последовательный порт. Вы можете изменить его на min 8 time 3, чтобы продолжать ждать (до 0,3 секунды между каждым байтом ), пока не будут прочитаны 8 байтов, но с тем недостатком, что всегда будет занимать не менее 0,3 секунды, если ответ короче, чем 8 байт и зависнет навсегда, если не будет ответа ).

Вы можете использовать awk -F'[^0-9]+' -v RS=R '{print $3, $2; exit}'с min 1 time 0. Это будет работать с awkреализациями, отличными от mawk(, которые настаивают на накоплении буфера, полного данных на входе, прежде чем начинать их обработку ).

В конце концов, чтение по одному байту за раз, как вы делаете в своем собственном ответе, является наиболее надежным. Вы можете добавить тайм-аут для учета терминалов, которые не отправляют ответ.

0
09.12.2019, 09:00
1 ответ

Из zshснаряда:

print -rC1 -- /**/y/x(/D)

Глоб **соответствует подкаталогам, а квалификатор (/D)glob указывает, что результирующие пути должны быть каталогами и что шаблон также должен соответствовать скрытым именам (, как и dotglobвbash).

Или приблизительный эквивалент из bashверсии 4 или более поздней (, т. е. установленной из Homebrew на macOS, а не по умолчаниюbash):

shopt -s globstar failglob dotglob
printf '%s\n' /**/y/x/

Параметр оболочки globstarв bashпозволяет использовать шаблон подстановки **, а failglobприводит к сбою сопоставления шаблонов с ошибкой, если совпадений нет. Поведение failglobиспользуется по умолчанию в zsh, как и доступность **.

findвероятно, будет быстрее:

find / -type d -path '*/y/x'

Это найдет любой каталог с именем x, находящийся в каталоге с именем yгде-то под /.

Или у вас может быть функциональная locateутилита, с помощью которой вы можете

locate '*/y/x'

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

1
28.01.2020, 02:17

Теги

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