笔记

笔记

我有一个目录,其中有一些子目录,其中包含文件。我有另一个目录,它有非常相似的子目录,但可能添加或删除了一些子目录。如何添加和删除子目录以使两个目录具有相同的结构?

有没有一种简单的方法可以使用命令或工具来执行此操作?或者我是否必须做一些更复杂的事情,例如搜索每个子目录并检查它是否有匹配的子目录?

答案1

为了这个答案,我使用了以下工具:

  • 重击
  • comm
  • find
  • xargs

我建议您使用最后 3 个实用程序的 GNU 版本,因为它们可以处理 NUL 分隔的记录。

首先,我们声明一些变量。有必要在所有这些变量中使用绝对路径名,因为我们将多次更改目录:

# The directories that will be compared
original_dir='/path/to/original/directory'
copy_dir='/path/to/copy/directory'

# Text files where we will save the structure of both directories
original_structure="${HOME}/original_structure.txt"
copy_structure="${HOME}/copy_structure.txt"

# Text files where we will separate each subdirectory
# depending on the action we will perform on them
dirs_to_add="${HOME}/dirs_to_add.txt"
dirs_to_remove="${HOME}/dirs_to_remove.txt"

保存两个目录的当前结构:

cd -- "${original_dir}"
find . \! -name '.' -type 'd' -print0 | sort -z > "${original_structure}"

cd -- "${copy_dir}"
find . \! -name '.' -type 'd' -print0 | sort -z > "${copy_structure}"

保存两个结构之间的差异:

comm -23 -z -- "${original_structure}" "${copy_structure}" > "${dirs_to_add}"
comm -13 -z -- "${original_structure}" "${copy_structure}" > "${dirs_to_remove}"

创建缺少的目录:

cd -- "${copy_dir}"
xargs -0 mkdir -p -- < "${dirs_to_add}"

删除不需要的目录:

cd -- "${copy_dir}"
xargs -0 rm -rf -- < "${dirs_to_remove}"

删除我们创建的用于保存临时信息的文本文件:

rm -- "${original_structure}" "${copy_structure}"
rm -- "${dirs_to_add}" "${dirs_to_remove}"

笔记

  • 此方法仅复制结构。它不保留所有者、权限或属性。我读到其他一些工具,例如rsync,可以保存它们,但我没有使用它们的经验。

  • 如果您想将上面的代码放入脚本中,请确保实现错误处理。例如,未能cd进入目录并在不正确的目录中进行操作可能会导致灾难性的后果。

答案2

像这样的 shell 函数可能会执行以下操作:

comparedirs() (
    cd -- "${1?}";
    for d in */; do
        ! [ -d ../"${2?}"/"$d" ] && printf "%s\n" "$d is in '$1' but not in '$2'"
    done
)

一个测试:

$ mkdir -p left/{a,b,c}
$ mkdir -p right/{a,c,d}
$ comparedirs left right
b/ is in 'left' but not in 'right'
$ comparedirs right left
d/ is in 'right' but not in 'left'

注意,这只查看子目录,而不是文件;并假设这些目录确实是同级目录,即您可以使用../name. (推广到其他情况留作下一个答案的练习。)

相关内容