![linux 两个文件夹之间的公共文件](https://linux22.com/image/1480404/linux%20%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%AC%E5%85%B1%E6%96%87%E4%BB%B6.png)
您好,我有 2 个目录,它们都包含目录和文件树。如果可能的话,我需要一个脚本来验证目录之间的公共文件,如果找到公共文件,我需要在 DIR2 中删除它并链接到 DIR1。
例子:
- DIR1 包括目录 abc1 , abc2 , abc3 ,且 abc1 包含文件 a.txt
- DIR2 包含目录 abc1 、 abc4,并且 abc4 包含文件 a.txt
- 脚本应删除 DIR2/abc4 中的 a.txt 并链接到 DIR1/abc/a.txt
该脚本最好采用 bash、awk、sed 或 perl 编写。
谢谢!
示例文件结构:
$ mkdir -- DIR1/ DIR1/abc1/ DIR1/abc2/ DIR1/abc3/ DIR2/ DIR2/abc1/ DIR2/abc4/
✔
$ touch -- DIR1/abc3/a.txt DIR2/abc4/a.txt
✔
$ tree
.
├── DIR1
│ ├── abc1
│ ├── abc2
│ └── abc3
│ └── a.txt
└── DIR2
├── abc1
└── abc4
└── a.txt
7 directories, 2 files
✔
答案1
没有理由编写脚本文件,有命令可以执行此操作而无需编写脚本。
该命令diff
将展示你的区别:
diff -r dir1/ dir2/
( -r
= 递归比较找到的所有子目录,参见手册)将打印位于的文件列表仅有的在任一目录中。
如果你还想检查同名文件的内容是否相同,那么你应该使用
diff --brief -r dir1/ dir2/
(--brief
=仅输出文件是否不同)。
如果你还想查看存在于只有一个目录,将其对应项视为空,您可以使用
diff --brief -Nr dir1/ dir2/
(-N
=将缺失的文件视为空)。
如果你想执行操作、命令
cp -Rnl dir1/ dir2/
会帮你完成。请注意-R
= 以递归方式复制目录(再次来自手册), 而-n
= 不会覆盖现有文件。
答案2
comm -12 <(ls folder1 | sort) <(ls folder2 | sort)
comm
打印两个文件的比较结果。-12
告诉它抑制文件 1 和文件 2 中的独特行。即仅打印公共行。<(...)
有助于使命令执行可用作文件替换。在替换中,列出文件夹的内容,然后按字母顺序排序。
就是这样。可以将其放入脚本中以查找所有子文件夹。
答案3
有一个名为tree
这将输出目录结构。
您可以将其传送到文本文件,然后从那里对其进行比较。
答案4
您应该能够在 bash 中轻松完成此操作。您要查找的用于进行比较的命令是md5sum
或diff
。
例如这里有一个脚本,它只比较命令行上指定的两个文件的 md5sum:
#!/bin/bash
FILE_A="$1"
FILE_B="$2"
if [ "`md5sum $FILE_A | awk '{print $1}'`" == "`md5sum $FILE_B | awk '{print $1}'`" ] ; then
echo "Same File"
else
echo "Files Differ"
fi
要遍历目录树,您需要使用递归。这是我很久以前编写的一个示例脚本,用于将文件名中带有空格的所有文件重命名为使用下划线而不是空格。
#!/bin/bash
rename 's/\ /_/g' ./*
currentdir=`pwd`
### for all files and directories in the current directory.
for filename in `ls` ; do
### if "filename" is a directory but not a softlink
if [ -d $filename ] && ! [ -h $filename ] ; then
cd "$filename"
$0 ### This causes the script to call itself. Recursion!
cd "$currentdir"
fi
done
然后使用 在目录之间创建文件链接ln -s dir1/File1 dir2/
。