求命令行工具或Bash脚本批量合并多设备同名文本文件,保留公共内容
多设备笔记文件合并解决方案
前置准备
先将其中一台设备的笔记文件夹完整同步到另一台设备上,例如将电脑A的~/notes/目录复制到电脑B的~/notes_from_a/路径,确保电脑B上同时存在两份完整的笔记目录:
- 电脑A的笔记目录:
~/notes_from_a/ - 电脑B本地原有笔记目录:
~/notes/
实现逻辑
针对每个同名笔记文件:
- 提取两个版本文件中
----------分隔线以上的独有内容,合并后去重(避免多端重复添加的内容多次出现) - 保留任意一个版本中分隔线及以下的公共内容(默认两端公共内容一致,若存在差异会在脚本中给出提示)
- 将合并后的独有内容 + 公共内容写入新的合并文件,可自由选择是否覆盖原文件
合并脚本
#!/bin/bash # 配置路径 A_DIR="$HOME/notes_from_a" B_DIR="$HOME/notes" OUTPUT_DIR="$HOME/notes_merged" # 若要直接覆盖原有文件,可修改为"$B_DIR" # 创建输出目录 mkdir -p "$OUTPUT_DIR" # 遍历A目录下的所有txt文件 for file in "$A_DIR"/*.txt; do # 提取文件名 filename=$(basename "$file") b_file="$B_DIR/$filename" # 检查B目录是否有同名文件,无则直接复制 if [ ! -f "$b_file" ]; then echo "跳过文件:$filename,B目录不存在同名文件" cp "$file" "$OUTPUT_DIR/" continue fi # 提取分隔线所在行号,分隔线标准为10个连续短横 sep_line_a=$(grep -n "^----------$" "$file" | head -n1 | cut -d: -f1) sep_line_b=$(grep -n "^----------$" "$b_file" | head -n1 | cut -d: -f1) # 检查文件是否存在标准分隔线,无则直接复制 if [ -z "$sep_line_a" ] || [ -z "$sep_line_b" ]; then echo "跳过文件:$filename,不存在标准分隔线" cp "$file" "$OUTPUT_DIR/" continue fi # 提取A、B设备分隔线以上的独有内容 content_a=$(head -n $((sep_line_a - 1)) "$file") content_b=$(head -n $((sep_line_b - 1)) "$b_file") # 提取公共内容(分隔线及以下,默认取A设备版本) common_content=$(tail -n +$sep_line_a "$file") common_content_b=$(tail -n +$sep_line_b "$b_file") # 公共内容不一致时给出提示 if [ "$common_content" != "$common_content_b" ]; then echo "警告:$filename 分隔线以下公共内容两端不一致,默认使用A设备的内容" fi # 合并独有内容,去重、去除多余空行、保留原有顺序 merged_upper=$(printf "%s\n%s" "$content_a" "$content_b" | awk 'NF && !seen[$0]++') # 写入合并后的文件 printf "%s\n\n%s" "$merged_upper" "$common_content" > "$OUTPUT_DIR/$filename" echo "已合并文件:$filename" done
使用说明
- 将上述代码保存为
merge_notes.sh - 赋予脚本执行权限:
chmod +x merge_notes.sh - 运行脚本:
./merge_notes.sh - 合并后的文件默认保存在
~/notes_merged/目录下,确认内容无误后可替换原有的~/notes/目录
可选调整
- 如果需要保留分隔线以上的空行,将
awk 'NF && !seen[$0]++'修改为awk '!seen[$0]++'即可 - 如果公共内容默认要使用B设备的内容,将
common_content=$(tail -n +$sep_line_a "$file")修改为common_content="$common_content_b"即可
内容的提问来源于stack exchange,提问作者freddie_ventura
相关产品推荐
相关产品推荐

