如何用实用脚本自动合并多个文件?

wen 实用脚本 3

本文目录导读:

如何用实用脚本自动合并多个文件?

  1. Python 脚本(最灵活)
  2. Bash Shell 脚本(Linux/Mac)
  3. Windows PowerShell 脚本
  4. 一键式实用脚本(Linux/Mac)
  5. 使用建议

Python 脚本(最灵活)

基础版:按顺序合并文本文件

#!/usr/bin/env python3
import os
import glob
def merge_files(input_pattern, output_file, add_separator=True):
    """
    合并匹配模式的所有文件
    Args:
        input_pattern: 文件匹配模式,如 "*.txt" 或 "data/*.csv"
        output_file: 输出文件名
        add_separator: 是否添加文件分隔标记
    """
    files = sorted(glob.glob(input_pattern))
    if not files:
        print(f"未找到匹配 {input_pattern} 的文件")
        return
    with open(output_file, 'w', encoding='utf-8') as outfile:
        for i, filepath in enumerate(files):
            print(f"处理: {filepath}")
            # 添加文件分隔标记
            if add_separator and i > 0:
                outfile.write("\n" + "="*50 + "\n")
                outfile.write(f"# 文件: {os.path.basename(filepath)} #\n")
                outfile.write("="*50 + "\n\n")
            # 读取并写入文件内容
            try:
                with open(filepath, 'r', encoding='utf-8') as infile:
                    content = infile.read()
                    outfile.write(content)
                    if not content.endswith('\n'):
                        outfile.write('\n')
            except Exception as e:
                print(f"读取 {filepath} 时出错: {e}")
    print(f"合并完成! 输出文件: {output_file}")
    print(f"共合并 {len(files)} 个文件")
# 使用示例
if __name__ == "__main__":
    # 合并所有txt文件
    merge_files("*.txt", "merged.txt")
    # 合并特定目录下的csv文件(不添加分隔符)
    merge_files("data/*.csv", "merged_data.csv", add_separator=False)

高级版:支持多种文件类型和格式

#!/usr/bin/env python3
import os
import argparse
from pathlib import Path
class FileMerger:
    def __init__(self):
        self.supported_formats = {
            '.txt': self.merge_text,
            '.csv': self.merge_csv,
            '.log': self.merge_text,
            '.json': self.merge_json,
        }
    def merge_text(self, files, output):
        """合并纯文本文件"""
        with open(output, 'w', encoding='utf-8') as out:
            for file in files:
                with open(file, 'r', encoding='utf-8') as f:
                    out.write(f.read() + '\n')
    def merge_csv(self, files, output):
        """合并CSV文件(保留表头)"""
        import csv
        with open(output, 'w', newline='', encoding='utf-8') as out:
            writer = csv.writer(out)
            header_written = False
            for file in files:
                with open(file, 'r', encoding='utf-8') as f:
                    reader = csv.reader(f)
                    for row in reader:
                        if not header_written:
                            writer.writerow(row)
                            header_written = True
                        else:
                            # 跳过后续文件的表头
                            if reader.line_num == 1:
                                continue
                            writer.writerow(row)
    def merge_json(self, files, output):
        """合并JSON文件为JSON数组"""
        import json
        all_data = []
        for file in files:
            with open(file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                if isinstance(data, list):
                    all_data.extend(data)
                else:
                    all_data.append(data)
        with open(output, 'w', encoding='utf-8') as f:
            json.dump(all_data, f, indent=2, ensure_ascii=False)
    def merge(self, input_dir, output_file, pattern='*', recursive=False):
        """通用合并方法"""
        input_path = Path(input_dir)
        if recursive:
            files = list(input_path.rglob(pattern))
        else:
            files = list(input_path.glob(pattern))
        # 按文件名排序
        files.sort()
        if not files:
            print(f"未找到匹配的文件")
            return
        # 根据文件扩展名选择合并方法
        ext = Path(files[0]).suffix.lower()
        merge_method = self.supported_formats.get(ext)
        if merge_method:
            merge_method(files, output_file)
            print(f"成功合并 {len(files)} 个文件到 {output_file}")
        else:
            print(f"不支持的文件格式: {ext}")
# 命令行接口
def main():
    parser = argparse.ArgumentParser(description='文件合并工具')
    parser.add_argument('input_dir', help='输入目录')
    parser.add_argument('output', help='输出文件')
    parser.add_argument('-p', '--pattern', default='*', help='文件匹配模式')
    parser.add_argument('-r', '--recursive', action='store_true', help='递归搜索')
    args = parser.parse_args()
    merger = FileMerger()
    merger.merge(args.input_dir, args.output, args.pattern, args.recursive)
if __name__ == "__main__":
    main()

Bash Shell 脚本(Linux/Mac)

#!/bin/bash
# 文件合并脚本
# 使用方法: ./merge_files.sh [选项] <输出文件>
set -e
# 默认配置
SEPARATOR=true
RECURSIVE=false
PATTERN="*.txt"
CLEAN_OUTPUT=true
# 显示帮助信息
show_help() {
    cat << EOF
使用方法: $0 [选项] <输出文件>
选项:
    -i <目录>       输入目录 (默认: 当前目录)
    -p <模式>       文件匹配模式 (默认: *.txt)
    -r              递归搜索子目录
    -n              不添加文件分隔符
    -h              显示帮助信息
示例:
    $0 merged.txt                    # 合并当前目录的所有txt文件
    $0 -i ./data -p "*.csv" merged.csv  # 合并data目录的所有csv文件
    $0 -r -p "*.log" all_logs.txt    # 递归合并所有log文件
EOF
    exit 0
}
# 解析命令行参数
INPUT_DIR="."
while getopts "i:p:rnh" opt; do
    case $opt in
        i) INPUT_DIR="$OPTARG" ;;
        p) PATTERN="$OPTARG" ;;
        r) RECURSIVE=true ;;
        n) SEPARATOR=false ;;
        h) show_help ;;
        *) show_help ;;
    esac
done
shift $((OPTIND-1))
OUTPUT_FILE="$1"
if [ -z "$OUTPUT_FILE" ]; then
    echo "错误: 请指定输出文件"
    show_help
fi
# 构建文件搜索命令
if [ "$RECURSIVE" = true ]; then
    FIND_CMD="find \"$INPUT_DIR\" -type f -name \"$PATTERN\" | sort"
else
    FIND_CMD="find \"$INPUT_DIR\" -maxdepth 1 -type f -name \"$PATTERN\" | sort"
fi
# 检查是否有匹配的文件
FILE_COUNT=$(eval "$FIND_CMD" | wc -l)
if [ "$FILE_COUNT" -eq 0 ]; then
    echo "错误: 在 $INPUT_DIR 中未找到匹配 $PATTERN 的文件"
    exit 1
fi
echo "找到 $FILE_COUNT 个文件"
echo "开始合并到 $OUTPUT_FILE..."
# 清空或创建输出文件
> "$OUTPUT_FILE"
# 合并文件
INDEX=0
eval "$FIND_CMD" | while read -r file; do
    INDEX=$((INDEX + 1))
    echo "处理 ($INDEX/$FILE_COUNT): $file"
    # 添加文件分隔符
    if [ "$SEPARATOR" = true ] && [ "$INDEX" -gt 1 ]; then
        echo -e "\n======= 文件分割线 =======" >> "$OUTPUT_FILE"
        echo "# 文件名: $(basename "$file")" >> "$OUTPUT_FILE"
        echo -e "==========================\n" >> "$OUTPUT_FILE"
    fi
    # 追加文件内容
    cat "$file" >> "$OUTPUT_FILE"
    # 确保文件末尾有换行
    echo "" >> "$OUTPUT_FILE"
done
echo "合并完成! 输出文件: $OUTPUT_FILE"
echo "共合并 $FILE_COUNT 个文件"

Windows PowerShell 脚本

# merge_files.ps1
param(
    [string]$InputDir = ".",
    [string]$Pattern = "*.txt",
    [string]$OutputFile = "merged.txt",
    [switch]$Recursive = $false,
    [switch]$AddSeparator = $true,
    [switch]$IncludeHeader = $true
)
# 显示使用说明
function Show-Help {
    Write-Host @"
文件合并 PowerShell 脚本
使用方法:
    .\merge_files.ps1 [-InputDir <目录>] [-Pattern <模式>] [-OutputFile <文件>] [-Recursive] [-AddSeparator] [-IncludeHeader]
参数说明:
    InputDir        : 输入目录 (默认: 当前目录)
    Pattern         : 文件匹配模式 (默认: *.txt)
    OutputFile      : 输出文件 (默认: merged.txt)
    Recursive       : 递归搜索子目录
    AddSeparator    : 添加文件分隔符 (默认: true)
    IncludeHeader   : 添加文件头信息 (默认: true)
示例:
    .\merge_files.ps1 -Pattern "*.csv" -OutputFile merged.csv
    .\merge_files.ps1 -Recursive -Pattern "*.log" -OutputFile all_logs.txt
"@
    exit
}
# 检查参数
if ($InputDir -eq "-h" -or $InputDir -eq "--help") {
    Show-Help
}
# 获取文件列表
$getFilesParams = @{
    Path = $InputDir
    Filter = $Pattern
    File = $true
}
if ($Recursive) {
    $getFilesParams.Recurse = $true
}
$files = Get-ChildItem @getFilesParams | Sort-Object Name
if ($files.Count -eq 0) {
    Write-Error "在 '$InputDir' 中未找到匹配 '$Pattern' 的文件"
    exit 1
}
Write-Host "找到 $($files.Count) 个文件"
Write-Host "开始合并到 '$OutputFile'..."
# 创建或清空输出文件
$null = New-Item -Path $OutputFile -ItemType File -Force
# 合并文件
$index = 0
foreach ($file in $files) {
    $index++
    Write-Progress -Activity "合并文件" -Status "处理中" -CurrentOperation $file.Name -PercentComplete ($index / $files.Count * 100)
    Write-Host "处理 ($index/$($files.Count)): $($file.Name)"
    # 添加文件头
    if ($IncludeHeader -and $index -gt 1) {
        Add-Content -Path $OutputFile -Value ""
        Add-Content -Path $OutputFile -Value "======= 文件分割线 ======="
        Add-Content -Path $OutputFile -Value "# 文件名: $($file.Name)"
        Add-Content -Path $OutputFile -Value "=========================="
        Add-Content -Path $OutputFile -Value ""
    }
    # 读取并合并文件内容
    $content = Get-Content -Path $file.FullName -Raw
    Add-Content -Path $OutputFile -Value $content
    # 添加换行
    if (-not $content.EndsWith("`n")) {
        Add-Content -Path $OutputFile -Value ""
    }
}
Write-Progress -Activity "合并文件" -Completed
Write-Host "合并完成! 输出文件: $OutputFile"
Write-Host "共合并 $($files.Count) 个文件"

一键式实用脚本(Linux/Mac)

#!/bin/bash
# 超级简单的文件合并命令(适合临时使用)
# 方法1:合并当前目录所有txt文件(按文件名排序)
cat $(ls *.txt | sort) > merged.txt
# 方法2:合并时添加文件名标记
for f in *.txt; do 
    echo "=== $f ===" >> merged.txt
    cat "$f" >> merged.txt
    echo "" >> merged.txt
done
# 方法3:合并所有日志文件(递归)
find . -name "*.log" -type f -exec cat {} \; > all_logs.txt
# 方法4:合并并显示进度
count=0
total=$(ls *.txt 2>/dev/null | wc -l)
for f in *.txt; do
    count=$((count+1))
    echo "处理 [$count/$total]: $f"
    cat "$f" >> merged.txt
done

使用建议

选择哪个脚本?

场景 推荐方案
临时、简单任务 Bash/PowerShell 一行命令
日常使用、多格式支持 Python 高级版
需要复杂处理(过滤、转换) Python 自定义修改
Windows 环境 PowerShell 脚本

最佳实践

  1. 先测试后使用:先用少量文件测试
  2. 备份原文件:合并操作不会修改原文件
  3. 注意编码问题:UTF-8 是最安全的编码
  4. 大文件处理:几百MB以上的文件建议用流式处理

这些脚本都可以直接复制保存为 .sh.ps1.py 文件使用,如果需要特定格式(如PDF、Word)的合并,可能需要专门的库。

抱歉,评论功能暂时关闭!