因此,我有一个脚本,它会遍历目录中的所有文件,并检查这些文件是否与同一目录中的任何其他文件包含相同的内容:
Check()
{
if [ -e "new.txt" ]
then
rm new.txt
fi
for item in "$2"/*
do
if [ ! -d "$item" ]
then
diff "$1" "$item">new.txt
if [ -s "new.txt" ]
then
echo "$1 $item"
echo "Yes"
fi
fi
done
}
Iterate()
{
for item in "$2"/*
do
if [ ! -d "$item" ]
then
Check $item $2
fi
done
}
Iterate $1 $2
还有狂欢
bash script.sh asd /home/ljuben
但是,当我运行脚本时,如果文件不包含相同的内容,它总是会回显“是”。
和想法?
答案1
您的脚本似乎没有使用其第一个参数。它被传递给Iterate
函数,然后再也不会出现。
但真正的问题是,您运行diff
两个文件的每个组合,然后查看差异的大小。对于不同的文件,差异的大小将不为零。因此,您的脚本会报告Yes
每个文件组合不同的, 不一样。
A
您还不必要地运行 file和B
两次之间的差异( A
vs.B
然后稍后B
vs. A
)。您可以通过仅生成一次文件列表,然后对其进行迭代来解决此问题。
替代脚本:
#!/bin/sh
if [ ! -d "$1" ]; then
printf 'Usage: %s directory\n' "$0" >&2
exit 1
fi
# set positional parameters to the list of files in the given directory
set -- "$1"/*
# while there's still files to process...
while [ "$#" -gt 0 ]; do
# skip over non-regular files
if [ ! -f "$1" ]; then
shift
continue
fi
# now process the first item in the list against the other ones
item=$1
# shift off the first item from the list
shift
# loop over the remaining items...
for name do
# we're still not interested in non-regular files
[ ! -f "$name" ] && continue
# if they are the same, report this
if cmp -s "$item" "$name"; then
printf '%s and %s has same content\n' "$item" "$name"
fi
done
done
如果您愿意,您仍然可以拥有这两个功能:
#!/bin/sh
if [ ! -d "$1" ]; then
printf 'Usage: %s directory\n' "$0" >&2
exit 1
fi
check () {
# now process the first item in the list against the other ones
item=$1
# shift off the first item from the list
shift
# loop over the remaining items...
for name do
# we're still not interested in non-regular files
[ ! -f "$name" ] && continue
# if they are the same, report this
if cmp -s "$item" "$name"; then
printf '%s and %s has same content\n' "$item" "$name"
fi
done
}
iterate () {
# set positional parameters to the list of files in the given directory
set -- "$1"/*
# while there's still files to process...
while [ "$#" -gt 0 ]; do
# only process regular files
if [ -f "$1" ]; then
check "$@" # checks the first item against the rest
fi
shift # get rid of the first item
done
}
iterate "$1"
请注意我们如何不让该check
函数生成自己的文件列表。相反,我们将文件列表传递给它。
对于懒人:
fdupes -1 /some/directory
答案2
您想diff
与以下-s
选项一起使用:
-s, --报告相同的文件
当两个文件相同时报告
您也不需要创建包含输出的文件,您只需在命令退出时进行测试diff
:
Check()
{
if [ -e "new.txt" ]
then
rm new.txt
fi
for item in "$2"/*
do
if [ ! -d "$item" ]
then
if diff -s "$1" "$item"
then
echo "$1 $item"
echo "Yes"
fi
fi
done
}
正如 Kusalananda 指出的那样,cmp
这可能是一个更好的选择,并且更便携。你可以使用:
if cmp -s "$1" "$item"
then
echo "$1 $item"
echo "Yes"
fi