首页 > 解决方案 > 如何在条件语句和循环中使用 diff 命令

问题描述

我创建了一个脚本,它递归地读取路径并将其目录和子目录打印到 csv 文件中以写入 excel 列。现在我想修改这个脚本,首先它会递归地读取一个路径并打印它的内容,然后找到这个路径与另一个路径的递归差异,我想打印是否有任何目录被更改。

第一个代码:

find path1 | while read file; do
  if [[ -d "$file" ]]; then
    echo $file > out.csv
  else
    echo...
  fi
done

第二个代码是:

diff -rq $path1 $path2 | while read file1; do
  if [[ "$file" != ]]; then
    echo Changed >> out.csv
  else
    echo no >> out.csv
  fi
done

现在我想合并这些代码,这样它将递归地打印 csv 文件中 path1 的所有内容,然后比较两个路径并在出现差异时打印更改。

标签: bash

解决方案


目前还不太清楚你想要完成什么。您的第一部分可以简化为一行:

find path1 -type d > out.csv

仅查找目录。(请注意,使用>overwrites out.csv,因此以前的内容无关紧要(您在示例中犯了一个错误))。

对于你的第二部分,你可以这样做:

diff <( cd path1 && find . -type d ) <( cd path2 && find . -type d )

这会抓取 path1 中的所有目录和 path2 中的所有目录,并以标准 diff 格式输出差异...

我正在使用进程替换 <( ),因此 bash 将输出视为文件。cd 到path1path2之前的 cd 会find阻止 find 输出path1/或其path2/结果(否则每一行都会不同)。你可以做类似的事情sed来剥离路径名。


另一方面,如果你的目标是学习 bash 循环,你可以这样做:

rm out.csv
find path | while read file; do 
    [[ -d $file ]] && echo $file >> out.csv
done

cat out.csv | while read file; do 
    [[ -e path2/${file#path1/} ]] || echo "file changed: $file"
done

请注意,与前一个示例不同,这不会打印 path2 中不在 path1 中的任何路径。

在这里,我使用了${file#path1/},它从每个文件名的前面剥离path1/(正如您现在正在查看的那样path2)。

希望这可以帮助。


推荐阅读