Linux 中仿 tree 輸出的 Shell 檔案
2024-05-29 一個比較完整的檔案寫完了放在gist上 Tree.sh (github.com)
某些環境基於某些原因實在是沒辦法,只能自己自幹一個這邊給一個 GPT 的作品,最基本基本的功能是有了
tree.sh
#!/bin/bash
# Function to print the folder name with color
function print_folder() {
local folder_name=$1
local COLOR_RESET="\033[0m"
local COLOR_FOLDER="\033[1;34m" # Blue color for folders
echo -e "${COLOR_FOLDER}${folder_name}/${COLOR_RESET}"
}
# Function to recursively print the directory tree structure
function print_tree() {
local directory=$1
local prefix=$2
local files=("$directory"/*)
local last_index=$((${#files[@]} - 1))
# Check if the directory is empty
if [ "$files" = "$directory/*" ]; then
return
fi
for i in "${!files[@]}"; do
local file="${files[$i]}"
local basename=$(basename "$file")
local new_prefix="$prefix"
if [ $i -eq $last_index ]; then
echo -n "${prefix}└── "
new_prefix="$prefix "
else
echo -n "${prefix}├── "
new_prefix="$prefix│ "
fi
if [ -d "$file" ]; then
print_folder "$basename"
print_tree "$file" "$new_prefix"
else
echo "$basename"
fi
done
}
# Check if a directory is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 <directory>"
exit 1
fi
# Remove trailing slash from the directory if it exists
directory=$(echo "$1" | sed 's:/*$::')
# Print the initial directory with color
print_folder "$(basename "$directory")"
print_tree "$directory" ""
使用的話跟 tree 差不多沒兩樣先給執行權限
chmod +x tree.sh
然後使用
./tree.sh testdir
輸出結果
testdir/
├── file1.txt
├── file2.txt
├── subdir1/
│ ├── file2.txt
│ ├── file3.txt
│ ├── subsubdir1/
│ │ └── file4.txt
│ └── subsubdir2/
│ └── file5.txt
└── subdir2/
├── file3.txt
├── file6.txt
└── subsubdir1/
└── file7.txt
精簡高壓版本
邏輯一樣的只是完全不管可讀性,能壓能壓版本
tree(){
[ -z "$1" ] && { echo "Usage: $0 <directory>"; exit 1; }
print_folder() { echo -e "\\033[1;34m${1}/\\033[0m"; }
print_tree() { local dir=$1 prefix=$2; local files=("$dir"/*)
print_tree_core() { [ $1 -ge ${#files[@]} ] && return
local idx=$1; local file="${files[$idx]}"
local base=$(basename "$file") new_prefix="$prefix"
([ $idx -eq $((${#files[@]} - 1)) ]) && {
echo -n "${prefix}└── "; new_prefix="$prefix "
} || { echo -n "${prefix}├── "; new_prefix="$prefix│ "
}; ([ -d "$file" ] && {
print_folder "$base"; print_tree "$file" "$new_prefix"
} || echo "$base"); print_tree_core $(($idx + 1))
}; [ "$files" = "$dir/*" ] && return || print_tree_core 0
}; dir=$(echo "$1" | sed 's:/*$::')
print_folder "$(basename "$dir")"; print_tree "$dir" ""
}
貼上之後直接呼叫 tree 就可以用了 (要是原本就有會被覆蓋功能,被蓋了重啟終端就好)
tree testdir
增加顯示有多少個檔案
tree(){
[ -z "$1" ] && { echo "Usage: $0 <directory>"; exit 1; }
print_folder() { echo -e "\\033[1;34m${1}/\\033[0m"; }
print_tree() { local dir=$1 prefix=$2; local files=("$dir"/*)
print_tree_core() { [ $1 -ge ${#files[@]} ] && return
local idx=$1; local file="${files[$idx]}"
local base=$(basename "$file") new_prefix="$prefix"
([ $idx -eq $((${#files[@]} - 1)) ]) && {
echo -n "${prefix}└── "; new_prefix="$prefix "
} || { echo -n "${prefix}├── "; new_prefix="$prefix│ "
}; [ -d "$file" ] && { dir_cnt=$((dir_cnt + 1))
print_folder "$base"; print_tree "$file" "$new_prefix"
} || { echo "$base"; file_cnt=$((file_cnt + 1))
}; print_tree_core $(($idx + 1))
}; [ "$files" = "$dir/*" ] && return || print_tree_core 0
}; dir=$(echo "$1" | sed 's:/*$::')
print_folder "$(basename "$dir")"; dir_cnt=0; file_cnt=0
print_tree "$dir"; echo -e "\n$dir_cnt directories, $file_cnt files"
}
增加顯示隱藏檔案
tree(){
[ -z "$1" ] && { echo "Usage: $0 <directory>"; exit 1; }
print_folder() { echo -e "\\033[1;34m${1}/\\033[0m"; }
print_tree() { local dir=$1 prefix=$2; local files
files=("${dir}"/.* "${dir}"/*); files=(${files[@]/*\*/})
print_tree_core() { [ $1 -ge ${#files[@]} ] && return
local idx=$1; local file="${files[$idx]}"
local base=$(basename "$file") new_prefix="$prefix"
([ "$base" == "." ] || [ "$base" == ".." ]) && {
print_tree_core $(($idx + 1)); return
}; ([ $idx -eq $((${#files[@]} - 1)) ]) && {
echo -n "${prefix}└── "; new_prefix="$prefix "
} || { echo -n "${prefix}├── "; new_prefix="$prefix│ "
}; [ -d "$file" ] && { dir_cnt=$((dir_cnt + 1))
print_folder "$base"; print_tree "$file" "$new_prefix"
} || { echo "$base"; file_cnt=$((file_cnt + 1))
}; print_tree_core $(($idx + 1))
}; [ ${#files[@]} -eq 0 ] && return || print_tree_core 0
}; dir=$(echo "$1" | sed 's:/*$::')
print_folder "$(basename "$dir")"; dir_cnt=0; file_cnt=0
print_tree "$dir"; echo -e "\n$dir_cnt directories, $file_cnt files"
}
魔法咒語
最後是魔法咒語,特地用函式包起來是要把路徑後置到後面,方便貼上直接些改
_(){ d=$(realpath "$1"); echo "$d"; find "$1" | sort | sed '1d;s|^'"$1"'| |;s/\/\([^/]*\)$/|-- \1/;s/\/[^/|]*/| /g'; };_ .
為什麼要用醜醜的 |-- 而不是更漂亮的 └── 是因為,用 Ascii 以外的符號很容易就噴亂碼,自己根據情況斟酌使用吧
沒有留言:
張貼留言