使用cmp命令结合sed处理后文件比对不一致问题排查
解决Bash脚本中cmp比对sed处理后内容始终显示不同的问题
问题描述
我写了一个Bash脚本,用来检查今日和昨日的文件差异:先用sed把文件里的during_schedule=YES;替换成during_schedule=NO;,再用cmp命令比对处理后的内容。但明明确认处理后两者内容一致,脚本却一直显示文件不同。原脚本如下:
#!/bin/bash todayfile=$(date +%d%m%Y) yesterdayfile=$(date -d "yesterday" +%d%m%Y) echo "----- POLICY -----" file1_in=$(sed 's|during_schedule=YES;|during_schedule=NO;|' /opt/custom_scripts/arch/policy_$todayfile.txt) file2_in=$(sed 's|during_schedule=YES;|during_schedule=NO;|' /opt/custom_scripts/arch/policy_$yesterdayfile.txt) file1="/opt/custom_scripts/arch/policy_$todayfile.txt" file2="/opt/custom_scripts/arch/policy_$yesterdayfile.txt" if cmp -s "$file1_in" "$file2_in"; then printf 'INFO: The file "%s" is the same as "%s"\n' "$file1" "$file2" else printf 'ERROR: The file "%s" is different from "%s"\n' "$file1" "$file2" fi
问题原因
核心错误在于:cmp命令的作用是比对文件,但你传给它的$file1_in和$file2_in是sed处理后输出的文本内容,而非文件名。当cmp尝试把这些文本内容当作文件名去打开时,必然找不到对应文件,因此直接返回“内容不同”的结果。
解决方案
下面提供三种可行的修正方法:
方法1:用diff结合进程比对(无需临时文件)
利用Bash的进程替换<(command),将sed的输出当作临时文件提供给diff,通过退出码判断内容是否一致:
#!/bin/bash todayfile=$(date +%d%m%Y) yesterdayfile=$(date -d "yesterday" +%d%m%Y) echo "----- POLICY -----" file1="/opt/custom_scripts/arch/policy_$todayfile.txt" file2="/opt/custom_scripts/arch/policy_$yesterdayfile.txt" if diff -q <(sed 's|during_schedule=YES;|during_schedule=NO;|' "$file1") <(sed 's|during_schedule=YES;|during_schedule=NO;|' "$file2") >/dev/null; then printf 'INFO: The file "%s" is the same as "%s"\n' "$file1" "$file2" else printf 'ERROR: The file "%s" is different from "%s"\n' "$file1" "$file2" fi
方法2:写入临时文件后用cmp比对
如果坚持使用cmp,可以先把sed处理后的内容写入临时文件,再比对临时文件:
#!/bin/bash todayfile=$(date +%d%m%Y) yesterdayfile=$(date -d "yesterday" +%d%m%Y) echo "----- POLICY -----" file1="/opt/custom_scripts/arch/policy_$todayfile.txt" file2="/opt/custom_scripts/arch/policy_$yesterdayfile.txt" # 创建临时文件 temp1=$(mktemp) temp2=$(mktemp) # 写入处理后的内容 sed 's|during_schedule=YES;|during_schedule=NO;|' "$file1" > "$temp1" sed 's|during_schedule=YES;|during_schedule=NO;|' "$file2" > "$temp2" # 比对临时文件 if cmp -s "$temp1" "$temp2"; then printf 'INFO: The file "%s" is the same as "%s"\n' "$file1" "$file2" else printf 'ERROR: The file "%s" is different from "%s"\n' "$file1" "$file2" fi # 清理临时文件 rm -f "$temp1" "$temp2"
方法3:直接字符串比较(适合小文件)
如果文件内容不大,可以直接用Bash的字符串相等判断来比对变量内容:
#!/bin/bash todayfile=$(date +%d%m%Y) yesterdayfile=$(date -d "yesterday" +%d%m%Y) echo "----- POLICY -----" file1="/opt/custom_scripts/arch/policy_$todayfile.txt" file2="/opt/custom_scripts/arch/policy_$yesterdayfile.txt" file1_in=$(sed 's|during_schedule=YES;|during_schedule=NO;|' "$file1") file2_in=$(sed 's|during_schedule=YES;|during_schedule=NO;|' "$file2") if [ "$file1_in" = "$file2_in" ]; then printf 'INFO: The file "%s" is the same as "%s"\n' "$file1" "$file2" else printf 'ERROR: The file "%s" is different from "%s"\n' "$file1" "$file2" fi
内容的提问来源于stack exchange,提问作者majan
相关产品推荐
相关产品推荐

