背景是 我在android手机上 /sdcard/DCIM/Camera 中有一些照片;
在mac-os上也有一些照片 /Volumes/XXXX DISK/picture/phone_a
这两个目录有大部分照片的文件名都是一样的。
使用adb pull,只拷贝手机比电脑多的照片作为备份。
可以这样做:
sh
#!/bin/bash
PHONE_DIR="/sdcard/DCIM/Camera"
MAC_DIR="/Volumes/XXXX DISK/picture/phone_a"
TMP_PHONE="/tmp/phone_files.txt"
TMP_MAC="/tmp/mac_files.txt"
TMP_COPY="/tmp/to_copy.txt"
adb shell "ls \"$PHONE_DIR\"" | sort > "$TMP_PHONE"
ls "$MAC_DIR" | sort > "$TMP_MAC"
comm -23 "$TMP_PHONE" "$TMP_MAC" > "$TMP_COPY"
if [[ ! -s "$TMP_COPY" ]]; then
echo "--- done ---"
exit 0
fi
echo "--- start copy ---"
echo "File size:"
cat $TMP_COPY | wc -l
while IFS= read -r filename; do
echo "copying: $PHONE_DIR/$filename -> $MAC_DIR"
adb pull "$PHONE_DIR/$filename" "$MAC_DIR"
done < "$TMP_COPY"
rm -f "$TMP_PHONE" "$TMP_MAC" "$TMP_COPY"
echo "--- done ---"
工作原理:
- 使用adb shell ls获取手机文件列表
- 使用ls获取电脑文件列表
- 用comm命令比较差异(-23参数显示只在第一个文件中存在的内容)
- 循环调用adb pull复制差异文件
mac上的 comm 指令用法
comm 是一个用于逐行比较两个已排序文件的 Linux/Unix 命令。它特别适合比较文件名列表,因为它能高效地识别出文件之间的差异。下面详细解释 comm -23 的工作原理:
基本输出格式
comm 命令默认输出三列结果:
- 第一列:只在第一个文件中出现的行
- 第二列:只在第二个文件中出现的行
- 第三列:在两个文件中都出现的行
例如:
bash
$ comm file1 file2
a
b
c
d
选项参数
-1、-2、-3 选项用于抑制对应的输出列:
-1:隐藏第一列(只存在于第一个文件的行)-2:隐藏第二列(只存在于第二个文件的行)-3:隐藏第三列(共同存在的行)
comm -23 详解
comm -23 file1 file2 表示:
-2:隐藏第二列(只存在于第二个文件的行)-3:隐藏第三列(共同存在的行)- 只保留第一列:即只存在于第一个文件中的行
在照片同步脚本中的应用
在你的脚本中:
bash
comm -23 "$TMP_PHONE" "$TMP_MAC" > "$TMP_COPY"
$TMP_PHONE:手机中的文件列表(第一个文件)$TMP_MAC:电脑中的文件列表(第二个文件)- 结果:只输出手机中有但电脑中没有的文件名
工作流程示例
假设:
- 手机文件:
a.jpg,b.jpg,c.jpg - 电脑文件:
a.jpg,c.jpg,d.jpg
执行过程:
-
排序后的文件:
bash# phone_files.txt a.jpg b.jpg c.jpg # mac_files.txt a.jpg c.jpg d.jpg -
comm -23比较结果:b.jpg -
最终只复制
b.jpg
重要前提
comm 命令要求输入文件必须是:
- 已排序 :使用
sort命令预处理 - 无重复项:每个文件名唯一
- 格式一致:相同的行尾格式(Unix LF)
与其他命令对比
| 命令 | 特点 | 适用场景 |
|---|---|---|
comm |
需要排序输入,输出格式化 | 比较两个已排序列表 |
diff |
不需要预排序,输出变更详情 | 比较文件内容差异 |
grep -F |
逐行查找,不需要排序 | 小文件或简单查找 |
awk |
灵活处理,可处理未排序文件 | 复杂比较或需要额外处理时 |
实际应用技巧
-
处理特殊字符:
bash# 使用 -b 忽略尾随空格 comm -23 -b <(adb shell ls "$PHONE_DIR" | sort) <(ls "$MAC_DIR" | sort) -
大小写敏感:
bash# 使用 -i 忽略大小写 comm -23 -i file1 file2 -
检查共同文件:
bash# 只显示共同文件(第三列) comm -12 file1 file2
在你的照片同步场景中,comm -23 是最佳选择,因为它:
- 高效处理大量文件
- 精确输出差异文件
- 资源消耗低(相比循环比较)
- 直接生成可操作的列表
理解 comm 命令能帮助你更好地处理文件比较任务,特别是在需要高效同步文件的场景中。