批量删除文件指定内容脚本

wen 实用脚本 1

本文目录导读:

批量删除文件指定内容脚本

  1. 使用方法
  2. 功能特点
  3. 注意事项

的Python脚本,这个脚本支持多种使用场景:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量删除文件指定内容脚本
支持功能:
1. 删除文件中包含指定关键字的行
2. 删除文件中指定位置的内容
3. 支持单个文件和批量文件夹处理
4. 支持多种文件编码
"""
import os
import re
import shutil
import argparse
from pathlib import Path
from datetime import datetime
from typing import List, Set, Optional
class FileContentCleaner:
    """文件内容清理器"""
    def __init__(self, encoding: str = 'utf-8'):
        """
        初始化清理器
        Args:
            encoding: 文件编码,默认utf-8
        """
        self.encoding = encoding
        self.backup_suffix = '.bak'
        self.processed_files = []
        self.failed_files = []
    def backup_file(self, file_path: str) -> None:
        """
        备份文件(可选功能)
        Args:
            file_path: 文件路径
        """
        backup_path = f"{file_path}{self.backup_suffix}"
        try:
            shutil.copy2(file_path, backup_path)
            print(f"已备份: {file_path} -> {backup_path}")
        except Exception as e:
            print(f"备份失败 {file_path}: {str(e)}")
    def remove_lines_by_keyword(self, file_path: str, keywords: List[str], 
                               case_sensitive: bool = False, 
                               keep_backup: bool = True) -> bool:
        """
        删除包含指定关键字的行
        Args:
            file_path: 文件路径
            keywords: 关键字列表
            case_sensitive: 是否区分大小写
            keep_backup: 是否保留备份
        Returns:
            bool: 是否处理成功
        """
        try:
            # 读取文件
            with open(file_path, 'r', encoding=self.encoding) as f:
                lines = f.readlines()
            # 记录原始行数
            original_count = len(lines)
            # 过滤行
            filtered_lines = []
            removed_count = 0
            for line in lines:
                should_remove = False
                for keyword in keywords:
                    if case_sensitive:
                        if keyword in line:
                            should_remove = True
                            break
                    else:
                        if keyword.lower() in line.lower():
                            should_remove = True
                            break
                if should_remove:
                    removed_count += 1
                    if not filtered_lines:  # 记录删除的行
                        pass
                else:
                    filtered_lines.append(line)
            # 如果有内容被删除
            if removed_count > 0:
                # 备份原文件
                if keep_backup:
                    self.backup_file(file_path)
                # 写入新内容
                with open(file_path, 'w', encoding=self.encoding) as f:
                    f.writelines(filtered_lines)
                print(f"✓ 处理 {file_path}")
                print(f"  删除 {removed_count} 行,剩余 {len(filtered_lines)} 行")
                return True
            else:
                print(f"- 文件 {file_path} 未找到匹配内容")
                return False
        except Exception as e:
            print(f"✗ 处理失败 {file_path}: {str(e)}")
            self.failed_files.append(file_path)
            return False
    def remove_lines_by_regex(self, file_path: str, pattern: str,
                            keep_backup: bool = True) -> bool:
        """
        使用正则表达式删除匹配的行
        Args:
            file_path: 文件路径
            pattern: 正则表达式模式
            keep_backup: 是否保留备份
        """
        try:
            with open(file_path, 'r', encoding=self.encoding) as f:
                content = f.read()
            # 编译正则表达式
            regex = re.compile(pattern, re.MULTILINE)
            # 查找匹配的内容
            matches = regex.findall(content)
            if matches:
                # 备份
                if keep_backup:
                    self.backup_file(file_path)
                # 删除匹配的行
                new_content = regex.sub('', content)
                # 清理多余的空行
                new_content = re.sub(r'\n{3,}', '\n\n', new_content)
                with open(file_path, 'w', encoding=self.encoding) as f:
                    f.write(new_content)
                print(f"✓ 处理 {file_path}")
                print(f"  删除 {len(matches)} 处匹配内容")
                return True
            else:
                print(f"- 文件 {file_path} 未找到匹配内容")
                return False
        except Exception as e:
            print(f"✗ 处理失败 {file_path}: {str(e)}")
            self.failed_files.append(file_path)
            return False
    def remove_line_range(self, file_path: str, start_line: int, 
                         end_line: int, keep_backup: bool = True) -> bool:
        """
        删除指定行号范围的内容
        Args:
            file_path: 文件路径
            start_line: 起始行号(从1开始)
            end_line: 结束行号
            keep_backup: 是否保留备份
        """
        try:
            with open(file_path, 'r', encoding=self.encoding) as f:
                lines = f.readlines()
            total_lines = len(lines)
            if start_line < 1 or end_line > total_lines or start_line > end_line:
                print(f"✗ 行号范围无效: {start_line}-{end_line}, 文件共 {total_lines} 行")
                return False
            # 备份
            if keep_backup:
                self.backup_file(file_path)
            # 删除指定范围的行
            del lines[start_line-1:end_line]
            with open(file_path, 'w', encoding=self.encoding) as f:
                f.writelines(lines)
            print(f"✓ 处理 {file_path}")
            print(f"  删除 {end_line - start_line + 1} 行")
            return True
        except Exception as e:
            print(f"✗ 处理失败 {file_path}: {str(e)}")
            self.failed_files.append(file_path)
            return False
    def process_files(self, file_paths: List[str], action: str, **kwargs) -> dict:
        """
        批量处理文件
        Args:
            file_paths: 文件路径列表
            action: 操作类型 ('keyword' 或 'regex' 或 'range')
            **kwargs: 操作参数
        Returns:
            dict: 处理结果统计
        """
        results = {
            'total': 0,
            'processed': 0,
            'failed': 0,
            'files': []
        }
        for file_path in file_paths:
            if not os.path.exists(file_path):
                print(f"✗ 文件不存在: {file_path}")
                results['failed'] += 1
                continue
            results['total'] += 1
            success = False
            if action == 'keyword':
                success = self.remove_lines_by_keyword(
                    file_path, 
                    kwargs.get('keywords', []),
                    kwargs.get('case_sensitive', False),
                    kwargs.get('keep_backup', True)
                )
            elif action == 'regex':
                success = self.remove_lines_by_regex(
                    file_path,
                    kwargs.get('pattern', ''),
                    kwargs.get('keep_backup', True)
                )
            elif action == 'range':
                success = self.remove_line_range(
                    file_path,
                    kwargs.get('start_line', 1),
                    kwargs.get('end_line', 1),
                    kwargs.get('keep_backup', True)
                )
            if success:
                results['processed'] += 1
                results['files'].append(file_path)
            else:
                results['failed'] += 1
        return results
    def get_files_by_extension(self, directory: str, extensions: List[str]) -> List[str]:
        """
        获取目录下指定扩展名的所有文件
        Args:
            directory: 目录路径
            extensions: 扩展名列表,如 ['.txt', '.log']
        """
        files = []
        for ext in extensions:
            pattern = f"**/*{ext}"
            files.extend([str(p) for p in Path(directory).glob(pattern)])
        return files
def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='批量删除文件指定内容')
    parser.add_argument('path', help='文件或目录路径')
    parser.add_argument('--keywords', nargs='+', help='要删除的关键字列表')
    parser.add_argument('--regex', help='正则表达式模式')
    parser.add_argument('--start-line', type=int, help='起始行号')
    parser.add_argument('--end-line', type=int, help='结束行号')
    parser.add_argument('--extensions', nargs='+', default=['.txt', '.log'], 
                       help='文件扩展名列表(处理目录时使用)')
    parser.add_argument('--encoding', default='utf-8', help='文件编码')
    parser.add_argument('--no-backup', action='store_true', help='不创建备份')
    parser.add_argument('--case-sensitive', action='store_true', help='区分大小写')
    args = parser.parse_args()
    # 创建清理器
    cleaner = FileContentCleaner(encoding=args.encoding)
    # 获取要处理的文件列表
    if os.path.isfile(args.path):
        files = [args.path]
    elif os.path.isdir(args.path):
        files = cleaner.get_files_by_extension(args.path, args.extensions)
        print(f"找到 {len(files)} 个文件")
    else:
        print(f"路径不存在: {args.path}")
        return
    # 执行操作
    if not files:
        print("没有找到要处理的文件")
        return
    # 显示操作信息
    print("=" * 50)
    print("开始处理文件...")
    # 处理关键字删除
    if args.keywords:
        print(f"删除包含以下关键字的行: {', '.join(args.keywords)}")
        if args.case_sensitive:
            print("注意: 区分大小写")
        results = cleaner.process_files(
            files,
            action='keyword',
            keywords=args.keywords,
            case_sensitive=args.case_sensitive,
            keep_backup=not args.no_backup
        )
    # 处理正则表达式删除
    elif args.regex:
        print(f"使用正则表达式: {args.regex}")
        results = cleaner.process_files(
            files,
            action='regex',
            pattern=args.regex,
            keep_backup=not args.no_backup
        )
    # 处理行号范围删除
    elif args.start_line and args.end_line:
        print(f"删除第 {args.start_line} - {args.end_line} 行")
        results = cleaner.process_files(
            files,
            action='range',
            start_line=args.start_line,
            end_line=args.end_line,
            keep_backup=not args.no_backup
        )
    else:
        print("请指定操作类型:--keywords 或 --regex 或 --start-line/--end-line")
        return
    # 显示结果
    print("=" * 50)
    print("处理完成!")
    print(f"总共: {results['total']} 个文件")
    print(f"成功: {results['processed']} 个文件")
    print(f"失败: {results['failed']} 个文件")
    if not args.no_backup:
        print("\n备份文件说明:")
        print("- 每个处理过的文件都会创建 .bak 备份")
        print("- 确认无误后可删除备份文件")
if __name__ == "__main__":
    main()

使用方法

安装依赖

这个脚本只使用Python标准库,无需额外安装。

基本用法

# 删除单个文件中包含指定关键字的行
python cleaner.py file.txt --keywords "敏感词" "需要删除的内容"
# 删除目录下所有.txt文件中的指定内容
python cleaner.py ./data --keywords "TODO" --extensions .txt .log
# 使用正则表达式删除
python cleaner.py file.txt --regex "^#.*$"  # 删除以#开头的行
# 删除指定行号范围
python cleaner.py file.txt --start-line 1 --end-line 10

高级用法

# 区分大小写删除
python cleaner.py file.txt --keywords "TODO" --case-sensitive
# 不创建备份
python cleaner.py file.txt --keywords "要删除的" --no-backup
# 指定编码
python cleaner.py file.txt --keywords "内容" --encoding utf-8

代码示例(直接在Python中使用)

# 使用类定义
cleaner = FileContentCleaner(encoding='utf-8')
# 删除关键字行
cleaner.remove_lines_by_keyword('file.txt', ['要删除', '敏感词'])
# 使用正则表达式
cleaner.remove_lines_by_regex('file.txt', r'\d{4}-\d{2}-\d{2}')
# 删除行范围
cleaner.remove_line_range('file.txt', 1, 10)
# 批量处理
files = cleaner.get_files_by_extension('./data', ['.txt', '.log'])
results = cleaner.process_files(files, 'keyword', keywords=['要删除'])

功能特点

  1. 安全备份:默认创建.bak备份文件
  2. 多种删除方式:关键字、正则、行号范围
  3. 批量处理:支持目录扫描
  4. 编码支持:可指定文件编码
  5. 结果统计:显示处理结果统计

注意事项

  1. 备份重要文件:虽然脚本会自动备份,但重要文件建议额外备份
  2. 测试先行:建议先在小文件上测试
  3. 定期清理:确认无误后删除备份文件

这个脚本适合处理日志清理、敏感信息删除、代码整理等场景,可以根据需要进一步定制和扩展。

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