В учебных целях я создал свой собственный скрипт find
, чтобы имитировать c функциональность -name
в исходной программе, он работает путем обхода каталогов с использованием алгоритма обхода деревьев с любым количеством дочерних элементов для каждого узла .
Сценарий:
#!/bin/sh
usage () {
echo "$(basename "$0") [OPTION]...
Traverse recursively the current directory tree and print based on filters.
Example: traverse --find=\"*.txt\" --exclude-dirs=\".git\"
Options:
-h, --help This help message
-f, --find Pattern to find
-e, --exclude-dirs Don't go into these folders
"
}
preorder() {
for line in * .*
do
# We don't want to go back to previous directory
[ "$line" = "." ] && continue
[ "$line" = ".." ] && continue
if [ -d "$line" ]; then \
# Checking if "exclude" flag set any condition
case "$EXCLUDE" in *"$line"*) continue ;; esac
cd "$line" 2> /dev/null || continue
# After entering the directory, run the preorder function again for that one.
preorder
else
# Does the line contain the name we want?
[ "$line" != "${line#$FIND}" ] && readlink -f "$line"
continue
fi
done
cd ..
}
for i in "$@"
do
case $i in
-h|--help)
usage
exit 0
;;
-f=*|--find=*)
FIND="${i#*=}"
;;
-e=*|--exclude-dirs=*)
EXCLUDE="${i#*=}"
;;
*)
usage
exit 1
;;
esac
done
current=$(pwd)
preorder
cd "$current" || exit 1
Я назвал его traverse
, поэтому используемый синтаксис будет traverse --find="*.txt"
для поиска всех файлов .txt
из текущего каталога и это подкаталоги.
Проблема в том, что я получаю много повторяющихся строк при выводе любого прогона, почти в 15 раз больше строк, чем при традиционном прогоне find -name "*.txt"
.
I ' я искал и искал возможную ошибку, но я не смог найти.
Может ли кто-нибудь помочь