本文目录导读:

单个文件去重(最常用)
Bash/Python 版本
#!/bin/bash
# 文件名: remove_duplicates.sh
# 用法: ./remove_duplicates.sh filename.txt
file=$1
if [ ! -f "$file" ]; then
echo "文件不存在: $file"
exit 1
fi
# 创建备份(推荐)
cp "$file" "${file}.bak"
# 删除重复行,保留首次出现的顺序
awk '!seen[$0]++' "$file" > tmp.txt && mv tmp.txt "$file"
echo "已处理: $file"
echo "备份文件: ${file}.bak"
批量处理多个文件
#!/bin/bash
# 批量处理当前目录所有 .txt 文件
for file in *.txt; do
if [ -f "$file" ]; then
# 备份原文件
cp "$file" "${file}.bak"
# 去重
awk '!seen[$0]++' "$file" > tmp.txt && mv tmp.txt "$file"
echo "已处理: $file"
fi
done
echo "所有文件处理完成!"
Python 版本(更灵活)
#!/usr/bin/env python3
# 文件名: remove_duplicates.py
# 用法: python3 remove_duplicates.py file1.txt file2.txt ...
import sys
import os
from pathlib import Path
def remove_duplicates(filepath):
"""删除文件中的重复行"""
try:
# 读取文件
with open(filepath, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 去重(保留顺序)
seen = set()
unique_lines = []
for line in lines:
if line not in seen:
unique_lines.append(line)
seen.add(line)
# 如果内容有变化
if len(unique_lines) != len(lines):
# 创建备份
backup_path = filepath + '.bak'
os.rename(filepath, backup_path)
# 写入去重后内容
with open(filepath, 'w', encoding='utf-8') as f:
f.writelines(unique_lines)
print(f"✓ {filepath} - 移除 {len(lines) - len(unique_lines)} 行重复")
else:
print(f"✓ {filepath} - 无重复行")
except Exception as e:
print(f"✗ 处理 {filepath} 时出错: {e}")
def main():
# 如果没有指定文件,处理当前目录所有 .txt 文件
if len(sys.argv) < 2:
files = list(Path('.').glob('*.txt'))
if not files:
print("未找到 .txt 文件")
return
print(f"处理 {len(files)} 个 .txt 文件...")
for file in files:
remove_duplicates(str(file))
else:
# 处理命令行指定的文件
for filepath in sys.argv[1:]:
if os.path.isfile(filepath):
remove_duplicates(filepath)
else:
print(f"文件不存在: {filepath}")
if __name__ == "__main__":
main()
高级功能版本(支持自定义选项)
#!/usr/bin/env python3
"""
批量删除文件重复行的完整工具
支持:目录递归、正则匹配、大小写敏感、自定义备份
"""
import os
import re
import sys
import argparse
from pathlib import Path
from datetime import datetime
def remove_duplicates(filepath, case_sensitive=True, regex=None, strip=True, backup=True):
"""
删除重复行的高级函数
"""
try:
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
lines = f.readlines()
# 处理每一行
processed = []
for line in lines:
# 去除首尾空白
if strip:
line_stripped = line.strip()
else:
line_stripped = line.rstrip('\n')
# 正则过滤
if regex and not re.search(regex, line_stripped):
processed.append(line)
continue
# 大小写处理
if not case_sensitive:
line_stripped = line_stripped.lower()
processed.append((line, line_stripped))
# 去重
seen = set()
unique_lines = []
for line, key in processed:
if key not in seen:
unique_lines.append(line)
seen.add(key)
# 检查是否有变化
if len(unique_lines) == len(lines):
return 0, "无重复行"
# 创建备份
if backup:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_path = f"{filepath}.bak_{timestamp}"
os.rename(filepath, backup_path)
else:
backup_path = None
# 写入去重后内容
with open(filepath, 'w', encoding='utf-8') as f:
f.writelines(unique_lines)
removed = len(lines) - len(unique_lines)
msg = f"移除 {removed} 行重复"
if backup_path:
msg += f" (备份: {backup_path})"
return removed, msg
except Exception as e:
return -1, f"错误: {e}"
def main():
parser = argparse.ArgumentParser(description='批量删除文件重复行')
parser.add_argument('path', nargs='*', help='文件或目录路径')
parser.add_argument('-r', '--recursive', action='store_true', help='递归处理子目录')
parser.add_argument('-e', '--extension', default='.txt', help='文件扩展名 (默认: .txt)')
parser.add_argument('-i', '--ignore-case', action='store_true', help='忽略大小写')
parser.add_argument('-g', '--regex', help='正则表达式过滤,只处理匹配的行')
parser.add_argument('--no-strip', action='store_true', help='不去除首尾空白')
parser.add_argument('--no-backup', action='store_true', help='不创建备份')
args = parser.parse_args()
# 获取要处理的文件列表
files_to_process = []
if args.path:
for p in args.path:
path = Path(p)
if path.is_file():
files_to_process.append(path)
elif path.is_dir():
if args.recursive:
files_to_process.extend(path.rglob(f'*{args.extension}'))
else:
files_to_process.extend(path.glob(f'*{args.extension}'))
else:
# 默认处理当前目录文件
files_to_process = list(Path('.').glob(f'*{args.extension}'))
if not files_to_process:
print(f"未找到 {args.extension} 文件")
return
# 统计
total_files = len(files_to_process)
total_removed = 0
processed_count = 0
errors = []
print(f"处理 {total_files} 个文件...")
print("-" * 50)
for filepath in files_to_process:
# 跳过备份文件
if '.bak' in str(filepath):
continue
removed, msg = remove_duplicates(
str(filepath),
case_sensitive=not args.ignore_case,
regex=args.regex,
strip=not args.no_strip,
backup=not args.no_backup
)
if removed >= 0:
processed_count += 1
total_removed += removed
status = "✓"
else:
errors.append((filepath, msg))
status = "✗"
print(f"{status} {filepath}: {msg}")
#
print("-" * 50)
print(f"完成! 处理 {processed_count}/{total_files} 个文件")
print(f"总共移除 {total_removed} 行重复")
if errors:
print(f"\n错误 ({len(errors)}):")
for filepath, error in errors:
print(f" {filepath}: {error}")
if __name__ == "__main__":
main()
单行命令(快速使用)
# 单个文件去重并保留原顺序 awk '!seen[$0]++' filename.txt > tmp && mv tmp filename.txt # 批量处理当前目录所有 .txt 文件 for f in *.txt; do awk '!seen[$0]++' "$f" > tmp && mv tmp "$f"; done # 使用 sort 去重(会打乱顺序) sort -u filename.txt > tmp && mv tmp filename.txt # 使用 sort 去重但保留第一次出现的顺序 cat -n filename.txt | sort -k2 -u | sort -k1 | cut -f2- > tmp && mv tmp filename.txt
使用示例
# 使用 Python 脚本处理所有 .txt 文件 python3 remove_duplicates.py # 递归处理子目录所有 .log 文件 python3 remove_duplicates.py -r -e .log /path/to/directory # 忽略大小写去重 python3 remove_duplicates.py -i myfile.txt # 只处理包含 "ERROR" 的行 python3 remove_duplicates.py -g "ERROR" logfile.txt # 使用 Bash 脚本处理单个文件 ./remove_duplicates.sh data.txt
注意事项
- 备份文件: 脚本会自动创建备份(文件名.bak)
- 编码问题: 如果文件是 GBK 编码,需要在 Python 脚本中修改 encoding 参数
- 大文件: 对于超大文件(>1GB),建议使用更高效的方法(如 sort -u)
- 内存占用: 脚本会将文件内容读取到内存,适合中小文件
选择最适合你需求的脚本即可!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播