Изучая базовые программы 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

Разберись сам!

Заворачивать

Иногда более ленивое кодирование оказывается эффективным!

Панцирь похож на швейцарский армейский нож для решения задач, надеюсь, вы узнали что-то новое. Если вам понравилось, поделитесь им с другими.