Изучая базовые программы bash, я наткнулся на ряд способов, с помощью которых мы можем сократить количество строк кода, необходимых для выполнения конкретной операции.
Эта статья покажет вам, как можно преобразовать сценарии оболочки в стандарты POSIX и сделать их более эффективными с точки зрения производительности. Но я рекомендую вам отнестись к этому с долей скептицизма и перепроверить перед использованием в своей работе.
Вот список подходов, которые мы должны применять:
- Используйте функции, а не несколько циклов
- Минимизируйте повторения кода
- Прочтите справочную страницу и попробуйте разные варианты
- Унифицировать входные и выходные линии
- Вариант использования вместо вложенных if-else
- Уменьшить вызов внешних команд
- Попробуйте эффективные алгоритмы
Не чистите картошку катаной.
Вот список программ, которые я пытался оптимизировать. Взгляните на код и попробуйте сравнить его с набором лабораторных.
Факториал числа
read -p ‘Enter n: ‘ n echo Factorial of $n = `seq -s “*” 1 $n | bc`
seq генерирует строку в диапазоне от 1 до n с символом «*» в качестве разделителя и передает ее в bc.
Число гласных в строке
read -p ‘Enter string: ‘ str echo No. of vowels = `echo $str | grep -o [aeiouAEIOU] | wc -l`
Все гласные в строке отфильтрованы до строк, которые подсчитываются wc.
Перевернуть заданную строку
read -p ‘Enter string: ‘ str echo Reverse = `echo $str | rev`
Это также можно использовать для проверки палиндромов!
Проверить високосный год
read -p ‘Enter year: ‘ y; ((y%=4)) [ $y -eq 0 ] && echo Leap year || echo not Leap year
Здесь я избегаю использования expr для арифметических операций, причина этого в том, что оболочка рекомендует использовать (( )) для того же самого. Поскольку expr является внешней командой, она не очень эффективна.
ПримечаниеМы не ставим ‘$’ внутри (( )),
для присваивания используйте t=$((i++)).
Вторая строка действует аналогично условному оператору.
Показать директорию, файлы и права доступа к файлам
look() { for i in *; do case $1 in d) [ -d $i ] && echo $i;; f) [ -f $i ] && echo $i;; fr) [ -f $i -a -r $i ] && echo $i;; fw) [ -f $i -a -w $i ] && echo $i;; fx) [ -f $i -a -x $i ] && echo $i;; esac done } printf “[Dirs]\n”; look d printf “[Files]\n” look f printf “[Files readable]\n” look fr printf “[Files writeable]\n” look fw printf “[Files executable]\n” look fx
Мы создаем перегруженную функцию, обратите внимание на уникальный способ передачи параметров.
Доступ к переданным параметрам осуществляется через $1 .. $n внутри функции.
Мин. и макс. заданного набора
read -p ‘Enter set of nos [eg: 1 2 3 4]: ‘ raw declare -a list=($raw); len=$(( ${#list[@]} — 1)) n=`printf “%s\n” “${list[@]}” | sort -g` declare -a sl=($n) echo min = ${sl[0]}, max = ${sl[len]}
Для этого мы преобразовали набор в массив и отсортировали его, таким образом, min находится в 0, а max в конце массива.
С.И. и К.И. с помощью АВК
OP() { read -p ‘Enter p, r, t: ‘ P R T case $1 in 1) awk -v P=$P -v R=$R -v T=$T ‘BEGIN {print “SI = “, P*R*T*0.01}’;; 2) awk -v P=$P -v R=$R -v T=$T ‘BEGIN {print “CI = “, (P*(1+R/100)^T)-P}’;; esac read -p ‘[Enter to continue]’ menu } menu() { clear printf “\n1.Simple Interest\n2.Compund Interest\n3.Exit\n” read -p ‘Enter choice: ‘ ch case $ch in 1) OP 1;; 2) OP 2;; 3) exit;; *) menu;; esac } menu
Зачем бояться, когда есть awk! (Производит десятичный вывод)
БД сотрудников
addEmp() { clear read -p ‘Enter emp name: ‘ name read -p ‘Enter emp no: ‘ no read -p ‘Enter Desig: ‘ dsg read -p ‘Enter Dept[CS/HR/EC]: ‘ dpt printf “\n $name \t\t $no \t\t\t $dpt \t $dsg” | tr -cs ‘A-Za-z’ >> empFile read -p ‘Do you want to add another emp info [y/n]: ‘ ch case $ch in y) addEmp;; *) menu;; esac } disp() { clear printf “\nEmployee Info Menu\n1. CS\n2. HR\n3. EC\n4. Non Managers\n” read -p ‘Enter choice: ‘ ch; ((ch — )) [ $ch -gt 3 ] && disp clear [ $ch -eq 3 ] && printf “\nNon Managers\n” && grep -v ‘MANAGER’ empFile && read && menu printf “\n Name \t\t eNo \t\t Dept \t Designation” printf “\n — — — — — — — — — — — — — — — — — — — — — \n” declare -a arr=(‘CS’ ‘HR’ ‘EC’); ch=${arr[$ch]} grep $ch empFile; c=`grep -c $ch empFile` printf “\nNumber of employees in $ch: $c\n\n” read -p ‘Hit return for menu ‘ menu } menu() { clear printf “Employee Info Record\n\nOptions:\n\n” printf “1. Add Employee details\n2. Display Employee Info\n3. Exit\n” read -p ‘Enter choice: ‘ ch case $ch in 1) addEmp;; 2) disp;; 3) exit;; *) menu;; esac } menu
Разберись сам!
Заворачивать
Иногда более ленивое кодирование оказывается эффективным!
Панцирь похож на швейцарский армейский нож для решения задач, надеюсь, вы узнали что-то новое. Если вам понравилось, поделитесь им с другими.