Улучшенный cd с поиском
Нашел на днях интересную задачку по программирвоанию. Задача по написанию консольного скрипта:
Улучшенная cd с поиском. При вводе cd Directory программа ищет каталог и переходит в него, если каталог с таким именем один. Если результатов несколько, предоставляет на выбор список.
То есть, например, мы находимся в корне проекта, в котором у нас есть 10 плагинов(папок с именем plugin). И чтобы не вписывать урлы вручную мы пишем только слово plugin и переходим в нужную папку в одно нажатие.
Консольные скрипты для Linux пишутся на bash
Этот язык - по сути командная оболочка UNIX, или просто набор команд, которые можно прописать в терминале. Поддерживается запуск команд и из файла, чем мы сейчас и займёмся.
Для создания bash-скрипта потребуется любой текстовый редактор, хоть Notepad++.
Создадим файл с именем ccd.sh
В первой строчке файла пишем:
#!/usr/bin/env bash
Сканируем все подпапки текущей директории:
altDir=( $(find -name "$1" -type d) )
Теперь в переменной altDir будет массив имён директорий.
Вместо $1 будет первый аргумент.
То есть, если прописать в командной строке
./ccd.sh abc
То в файле сработает команда:
altDir=( $(find -name "abc" -type d) )
Команда find
ищет файлы и папки.
Ключ -name
позволяет искать по имени. Оператор регистрозависим! Если вам нужно игнорировать регистр - вместо name
напишите iname
.
Ключ -type
указывает на тип искомого. d
- означает директории.
Сразу же проверим была ли найдена хоть одна директория.
if [ "${altDir[0]}" == "" ]
then
#ничего не найдено
echo "Директории не найдены"
fi
Тут всё просто - если нулевой элемент массива altDir отсутствует - значит массив пустой.
Дополним условие оператором else
if [ "${altDir[0]}" == "" ]
then
#ничего не найдено
echo "Директории не найдены"
else
#найдена одна или более директорий
if [ "${altDir[1]}" == "" ]
then
#найдена только одна директория
cd ${altDir[0]}
exec bash
else
#найдено несколько директорий
fi
fi
Тут логика тоже простоая.
Если массив не является пустым - проверяем его первый элемент.
Если его нет - значит в массиве есть только один элемент(нулевой) и мы сразу же переходим в найденную директорию.
Если первый массив не пустой - значит в массиве более одного значения, а именно 2 и более.
Для вывода этих значений обойдём переменную altDir циклом:
for ((i=0; i < ${#altDir[*]} ; i++))
do
let "num = i + 1"
echo $num ${altDir[$i]}
done
В цикле я выведу номер элемента(увеличенный на 1) и имя директории.
Далее нам нужно "спросить" у пользователя - в какую директорию нужно перейти.
Для этого используется оператор read
read dir
Ответ пользователя будет записан в переменную dir.
Если пользователь передумал - то добавим возможность отмены при нажатии нуля.
if [ $dir == 0 ]
then
#в случае отмены - прекращаем работу скрипта
exit 0
fi
Оператор exit
завершает работу. Код 0 говорит об успешном завершении работы скрипта.
Ну и переход в ужную директорию.
#переходим в нужную директорию
let "dir = dir - 1"
cd ${altDir[dir]}
exec bash
Полный листинг кода
#!/usr/bin/env bash
# сканируем все подпапки текущей директории
altDir=( $(find -name "$1" -type d) )
if [ "${altDir[0]}" == "" ]
then
#ничего не найдено
echo "Директории не найдены"
else
#найдена одна или более директорий
if [ "${altDir[1]}" == "" ]
then
#найдена только одна директория
cd ${altDir[0]}
exec bash
else
#найдено несколько директорий
echo "Выберите директорию"
echo "0 Отмена"
for ((i=0; i < ${#altDir[*]} ; i++))
do
let "num = i + 1"
echo $num ${altDir[$i]}
done
#предлагаем ввести номер нужной и заносим в переменную dir
read dir
if [ $dir == 0 ]
then
#в случае отмены - прекращаем работу скрипта
exit 0
fi
#переходим в нужную директорию
let "dir = dir - 1"
cd ${altDir[dir]}
exec bash
fi
fi
Сохранение
Я сохранил файл в папке ~/scripts/ccd.sh
Делаем на него символическую ссылку
ln -s ~/scripts/ccd.sh /usr/bin/ccd
Делаем его исполняемым
chmod u+x /usr/bin/ccd
Если получите отказ в доступе - введите перед командой sudo
Использование
Открываете нужную директорию и пишите:
ccd foldername
Если вы помните только часть имени папки:
ccd folder*
Если вы не помните начало имени папки - то заключите аргумент в кавычки:
ccd "*name"
Или:
ccd "*name*"
Традиционная гифка в конце:)
Материал подготовлен автором @tristamoff