Luobxx'Blog

shell脚本实现文件管理

\(\Huge{shell脚本实现文件管理}\)

脚本构思

今天在整理自己写过的笔记,突然想要整理出一张思维导图,方便检查。

由于平时在电脑上记笔记,使用的软件是Typora,然后下的有一个插件:Typora Plugin,这个插件里内置的有markmap。我的笔记都是存放在一个文件夹里的,根据Markdown的链接语法,如果我们可以将这个文件夹以及子文件夹和文件用markdown的标题语法呈现出,然后根据markmap来呈现出整个文件目录的思维导图。

那么这个步骤可以用脚本来完成,我选择使用的是shell脚本编写。

我们可以整个文件目录,对于文件,我们先按一定格式(# []())来输出文件路径,然后递归查找,如果是文件,就将其文件路径按格式输出。“#”在markdown中表示第几级标题,可以根据递归的层数来输出相应的数量。

由于文件里的一些其他内容我并不想要用在最终的思维导图中实现,因此在实现的过程中需要跳过。因此需要根据文件名、文件类型来筛选或跳过输出的内容。

脚本实现

#!/bin/bash

# 指定开始遍历的根目录
# 若将该脚本放入要整理的文件夹内,那么根目录用"."表示
start_directory="your_directory_path_here"

# 指定需要排除的文件或文件夹名称
exclude_list=("exclude_file_or_folder_name1" "exclude_file_or_folder_name2")

# 指定不以标题形式列出的文件夹名称或文件类型(扩展名)
no_title_list=("folder1" "folder2" "ext1" "ext2")

# 指定只列出文件夹的名称,忽略其内容
only_list_folders=("folder3" "folder4")

# 创建或清空思维导图.md文件(若文件存在则覆盖)
output_file="思维导图.md"
> "$output_file"

# 函数:检查是否在排除列表中
function is_excluded {
    local item="$1"
    for exclude_item in "${exclude_list[@]}"; do
        if [[ "$item" == "$exclude_item" ]]; then
            return 0
        fi
    done
    return 1
}

# 函数:检查是否在不以标题形式列出列表中
function is_in_no_title_list {
    local item="$1"
    for no_title_item in "${no_title_list[@]}"; do
        if [[ "$item" == "$no_title_item" ]]; then
            return 0
        fi
    done
    return 1
}

# 函数:检查是否在只列出文件夹列表中
function is_only_list_folder {
    local item="$1"
    for only_list_item in "${only_list_folders[@]}"; do
        if [[ "$item" == "$only_list_item" ]]; then
            return 0
        fi
    done
    return 1
}

# 函数:递归遍历目录和子目录
function list_files {
    local directory="$1"
    local level="$2"
    
    local indent=$(printf '#%.0s' $(seq 1 $((level + 1))))
    
    echo "${indent} $(basename "$directory")" >> "$output_file"
    
    # 如果目录在只列出文件夹列表中,则返回
    if is_only_list_folder "$(basename "$directory")"; then
        return
    fi

    for file in "$directory"/*; do
        local filename=$(basename "$file")
        
        # 检查是否在排除列表中
        if is_excluded "$filename"; then
            continue
        fi
        
        if [ -d "$file" ]; then
            list_files "$file" $((level + 1))
        else
            local extension="${filename##*.}"
            
            # 检查是否在不以标题形式列出列表中
            if is_in_no_title_list "$(basename "$directory")" || is_in_no_title_list "$extension"; then
                local relative_path=$(realpath --relative-to="$start_directory" "$file")
                echo "[$filename]($relative_path)" >> "$output_file"
            else :
                local relative_path=$(realpath --relative-to="$start_directory" "$file")
                echo "${indent}# [$filename]($relative_path)" >> "$output_file"
            fi
        fi
    done
}

# 调用函数遍历根目录
list_files "$start_directory" 0

脚本说明

  1. start_directory:
    • 指定开始遍历的根目录路径。
  2. exclude_list:
    • 一个包含需要排除的文件或文件夹名称的数组。
  3. no_title_list数组
    • 指定不以标题形式列出的文件夹名称或文件类型(扩展名)。
  4. only_list_folders数组
    • 一个包含只列出文件夹名称而忽略其内容的数组。
  5. output_file:
    • 输出的Markdown文件的名称。在脚本开始时清空该文件。
  6. is_excluded函数:
    • 检查给定的文件或文件夹名称是否在排除列表中。
  7. is_in_no_title_list函数
    • 检查是否在不以标题形式列出列表中。
  8. is_only_list_folder函数
    • 检查是否在只列出文件夹列表中。
  9. list_files函数:
    • 递归遍历目录和子目录,参数为当前目录路径和层级。
    • 根据层级数生成相应数量的#符号。
    • 使用basename获取文件或文件夹名称。
    • 检查文件或文件夹是否在排除列表中,如果在则跳过。
    • 检查文件是否是忽视的类型,如果是则跳过。
    • 如果是文件夹,递归调用list_files函数。
    • 如果是文件,获取相对路径并以[文件名](文件相对地址)的格式写入思维导图.md文件。
    • 如果文件夹在标题列表中,文件名用标题格式列出。
posted @ 2026-01-15 22:15  鱼香_rose  阅读(0)  评论(0)    收藏  举报