# Это даст некоторый выигрыш в скорости.
+
Jordi Sanfeliu дал согласие на публикацию своего сценария tree .
Пример A-19. tree: Вывод дерева каталогов
#!/bin/sh
# @(#) tree 1.1 30/11/95 by Jordi Sanfeliu
# email: mikaku@fiwix.org
#
# Начальная версия: 1.0 30/11/95
# Следующая версия: 1.1 24/02/97 Now, with symbolic links
# Исправления : Ian Kjos, поддержка недоступных каталогов
# email: beth13@mail.utexas.edu
#
# Tree -- средство просмотра дерева каталогов (очевидно :-) )
#
# ==> Используется в данном документе с разрешения автора сценария, Jordi Sanfeliu.
# ==> Комментарии, добавленные автором документа.
# ==> Добавлено "окавычивание" аргументов.
search () {
for dir in `echo *`
# ==> `echo *` список всех файлов в текущем каталоге, без символов перевода строки.
# ==> Тот же эффект дает for dir in *
# ==> но "dir in `echo *`" не обрабатывет файлы, чьи имена содержат пробелы.
do
if [ -d "$dir" ] ; then # ==> Если это каталог (-d)...
zz=0 # ==> Временная переменная, для сохранения уровня вложенности каталога.
while [ $zz != $deep ] # Keep track of inner nested loop.
do
echo -n "| " # ==> Показать символ вертикальной связи,
# ==> с 2 пробелами и без перевода строки.
zz=`expr $zz + 1` # ==> Нарастить zz.
done
if [ -L "$dir" ] ; then # ==> Если символическая ссылка на каталог...
echo "+---$dir" `ls -l $dir | sed 's/^.*'$dir' //'`
# ==> Показать горизонтальный соединитель и имя связянного каталога, но...
# ==> без указания даты/времени.
else
echo "+---$dir" # ==> Вывести горизонтальный соединитель...
# ==> и название каталога.
if cd "$dir" ; then # ==> Если можно войти в каталог...
deep=`expr $deep + 1` # ==> Нарастить уровень вложенности.
search # рекурсия ;-)
numdirs=`expr $numdirs + 1` # ==> Нарастить счетчик каталогов.
fi
fi
fi
done
cd .. # ==> Подняться на один уровень вверх.
if [ "$deep" ] ; then # ==> Если depth = 0 (возвращает TRUE)...
swfi=1 # ==> выставить признак окончания поиска.
fi
deep=`expr $deep - 1` # ==> Уменьшить уровень вложенности.
}
# - Main -
if [ $# = 0 ] ; then
cd `pwd` # ==> Если аргумент командной строки отсутствует, то используется текущий каталог.
else
cd $1 # ==> иначе перейти в заданный каталог.
fi
echo "Начальный каталог = `pwd`"
swfi=0 # ==> Признак завершения поиска.
deep=0 # ==> Уровень вложенности.
numdirs=0
zz=0
while [ "$swfi" != 1 ] # Пока поиск не закончен...
do
search # ==> Вызвать функцию поиска.
done
echo "Всего каталогов = $numdirs"
exit 0
# ==> Попробуйте разобраться в том как этот сценарий работает.
Noah Friedman дал разрешение на публикацию своей библиотеки функций для работы со строками , которая, по сути, воспроизводит некоторые библиотечные функции языка C.
Пример A-20. Функции для работы со строками
#!/bin/bash
# string.bash --- эмуляция библиотеки функций string(3)
# Автор: Noah Friedman
# ==> Используется с его разрешения.
# Дата создания: 1992-07-01
# Дата последней модификации: 1993-09-29
# Public domain
# Преобразование в синтаксис bash v2 выполнил Chet Ramey
# Комментарий:
# Код:
#:docstring strcat:
# Порядок использования: strcat s1 s2
#
# Strcat добавляет содержимое переменной s2 к переменной s1.
#
# Пример:
# a="foo"
# b="bar"
# strcat a b
# echo $a
# => foobar
#
#:end docstring:
###;;;autoload
function strcat ()
{
local s1_val s2_val
s1_val=${!1} # косвенная ссылка
s2_val=${!2}
eval "$1"=\'"${s1_val}${s2_val}"\'
# ==> eval $1='${s1_val}${s2_val}' во избежание проблем,
# ==> если одна из переменных содержит одиночную кавычку.
}
#:docstring strncat:
# Порядок использования: strncat s1 s2 $n
#
# Аналог strcat, но добавляет не более n символов из
# переменной s2. Результат выводится на stdout.
#
# Пример:
# a=foo
# b=barbaz
# strncat a b 3
# echo $a
# => foobar
#
#:end docstring:
###;;;autoload
function strncat ()
{
local s1="$1"
local s2="$2"
local -i n="$3"
local s1_val s2_val
s1_val=${!s1} # ==> косвенная ссылка
s2_val=${!s2}
if [ ${#s2_val} -gt ${n} ]; then
s2_val=${s2_val:0:$n} # ==> выделение подстроки
fi
eval "$s1"=\'"${s1_val}${s2_val}"\'
# ==> eval $1='${s1_val}${s2_val}' во избежание проблем,
# ==> если одна из переменных содержит одиночную кавычку.
}
#:docstring strcmp:
# Порядок использования: strcmp $s1 $s2
#
# Strcmp сравнивает две строки и возвращает число меньше, равно
# или больше нуля, в зависимости от результатов сравнения.
#:end docstring:
###;;;autoload
function strcmp ()
{
[ "$1" = "$2" ] && return 0
[ "${1}" '<' "${2}" ] > /dev/null && return -1
return 1
}
#:docstring strncmp:
# Порядок использования: strncmp $s1 $s2 $n
#
# Подобна strcmp, но сравнивает не более n символов
#:end docstring:
###;;;autoload
function strncmp ()
{
if [ -z "${3}" -o "${3}" -le "0" ]; then
return 0
fi
if [ ${3} -ge ${#1} -a ${3} -ge ${#2} ]; then
strcmp "$1" "$2"
return $?
else
s1=${1:0:$3}
s2=${2:0:$3}
strcmp $s1 $s2
return $?
fi
}
#:docstring strlen:
# Порядок использования: strlen s
Читать дальше