-
-
Save takuzoo3868/65b0940747175301854000ce7e0b96b7 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| # treeを擬似的に再現したスクリプト | |
| dir_count=0 | |
| file_count=0 | |
| traverse() { | |
| dir_count=$(expr $dir_count + 1) | |
| local directory=$1 | |
| local prefix=$2 | |
| local children=($(ls $directory)) | |
| local child_count=${#children[@]} | |
| for idx in "${!children[@]}"; do | |
| local child="${children[$idx]}" | |
| local child_prefix="│ " | |
| local pointer="├── " | |
| if [ $idx -eq $(expr ${#children[@]} - 1) ]; then | |
| pointer="└── " | |
| child_prefix=" " | |
| fi | |
| echo "${prefix}${pointer}$child" | |
| [ -d "$directory/$child" ] && | |
| traverse "$directory/$child" "${prefix}$child_prefix" || | |
| file_count=$(expr $file_count + 1) | |
| done | |
| } | |
| root="." | |
| [ "$#" -ne 0 ] && root="$1" | |
| echo $root | |
| traverse $root "" | |
| echo | |
| echo "$(expr $dir_count - 1) directories, $file_count files" |
You should replace
expr will launch a new process, while $(( )) is a bash internal.
For the same reason, and to handle filenames with spaces, you should replace ($(ls $directory)) with ("$directory"/*). Then you'll have to cut out the directory name.
Here is the result :
#!/usr/bin/env bash
dir_count=0
file_count=0
traverse() {
dir_count=$((dir_count + 1))
local directory=$1
local prefix=$2
local children=("$directory"/*)
local child_count=${#children[@]}
for idx in "${!children[@]}"
do local child="${children[$idx]}"
child=${child##*/}
local child_prefix="│ "
local pointer="├── "
if [ $idx -eq $(( ${#children[@]} - 1)) ]; then
pointer="└── "
child_prefix=" "
fi
echo "${prefix}${pointer}$child"
[ -d "$directory/$child" ] &&
traverse "$directory/$child" "$prefix$child_prefix" ||
file_count=$((file_count + 1))
done
}
root="."
[ "$#" -ne 0 ] && root="$1"
echo $root
traverse $root ""
echo
echo "$((dir_count - 1)) directories, $file_count files"
The output doesn't handle singular and plural cases as the actual tree command does.
You should replace (expr...)with(( ... )). expr will launch a new process, while $(( )) is a bash internal.
For the same reason, and to handle filenames with spaces, you should replace ($(ls $directory)) with ("$directory"/*). Then you'll have to cut out the directory name.
Here is the result :
...
Thanks a lot, @Vouze! Just updated this script to show trailing backslash for folders, not to print strange tail if the directory is empty, and colored folders and executable files in the tree:
#!/usr/bin/env bash
dir_count=0
file_count=0
traverse() {
dir_count=$((dir_count + 1))
local directory=$1
local prefix=$2
local children=("$directory"/*)
local child_count=${#children[@]}
for idx in "${!children[@]}"
do local child="${children[$idx]}"
child=${child##*/}
local child_prefix="│ "
local pointer="├── "
if [ $idx -eq $(( ${#children[@]} - 1)) ]; then
pointer="└── "
child_prefix=" "
fi
if [ -e $directory/$child ]; then
if [ -d "$directory/$child" ]; then
echo -e "${prefix}${pointer}\033[1;34m$child/\033[0m"
traverse "$directory/$child" "$prefix$child_prefix"
else
if [ -x $directory/$child ]; then
echo -e "${prefix}${pointer}\033[0;32m$child\033[0m"
else
echo "${prefix}${pointer}$child"
fi
file_count=$((file_count + 1))
fi
fi
done
}
root="."
[ "$#" -ne 0 ] && root="$1"
echo $root
traverse $root ""
echo
echo "$((dir_count - 1)) directories, $file_count files"
since i was too lazy to install tree, thank you very much