我需要创建一个shell脚本,“在当前工作目录下列出所有相同的子目录(递归)。”
我是shell脚本的新手。我该如何处理?
对我来说,这意味着:
md5sum
(?)并继续对目录中的每个子目录进行比例(递归?)这本来是我写过的最复杂的程序,所以我假设我只是不知道有一些shell命令要为我做大部分工作?
即,我应该怎样接近这个?所有其他部分都是关于谷歌搜索,直到我发现shell命令为我做了90%。
(对于我以前无法完成的任务,在这部分上取零,需要知道将来如何处理它。)
答案 0 :(得分:1)
我很惊讶地听到有一个特殊的Unix工具或标准Unix工具的特殊用法来完成您所描述的内容。也许你对任务的理解比任务提供者的意图更复杂。也许与“相同”的东西有关。通常,不允许使用硬链接目录,因此这也许并不意味着。
无论如何,我通过为树中的所有节点创建校验和来实现此任务,即。即递归:
为所有元素创建校验和后,搜索重复项(通过对所有元素列表进行排序并搜索连续行)。
快速解决方案可能是这样的:
SELECT VendorState, InvoiceTotal
FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID
WHERE VendorState > ALL
(SELECT COUNT(InvoiceTotal)
FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID
WHERE VendorState > 1)
这个脚本使用了两个可能不太清楚的技巧,所以我提到它们:
#!/bin/bash
dirchecksum() {
if [ -f "$1" ]
then
checksum=$(md5sum < "$1")
elif [ -d "$1" ]
then
checksum=$(
find "$1" -maxdepth 1 -printf "%P " \( ! -path "$1" \) \
-exec bash -c "dirchecksum {}" \; |
md5sum
)
fi
echo "$checksum"
echo "$checksum $1" 1>&3
}
export -f dirchecksum
list=$(dirchecksum "$1" 3>&1 1>/dev/null)
lastChecksum=''
while read checksum _ path
do
if [ "$checksum" = "$lastChecksum" ]
then
echo "duplicate found: $path = $lastPath"
fi
lastChecksum=$checksum
lastPath=$path
done < <(sort <<< "$list")
,可以find -exec
(在它下面完成),然后调用export -f
来执行它。最后的排序使用通过fd 3给出的列表作为输入。
答案 1 :(得分:1)
也许是这样的:
$ find -type d -exec sh -c "echo -n {}\ ; sh -c \"ls -s {}; basename {}\"|md5sum " \; | awk '$2 in a {print "Match:"; print a[$2], $1; next} a[$2]=$1{next}'
Match:
./bar/foo ./foo
find
所有目录:find -type d
,输出:
.
./bar
./bar/foo
./foo
ls -s {}; basename {}
将打印简化的目录列表和列出的目录的基本名称,例如目录foo
:ls -s foo; basename foo
total 0
0 test
foo
这些将涵盖每个目录中的文件,它们的大小和目录名称。该输出将发送到md5sum
以及dir:
. 674e2573b49826d4e32dfe81d9680369 -
./bar 4c2d588c5fa9781ad63ad8e86e575e01 -
./bar/foo ff8d1569685be86366f18ea89851db35 -
./foo ff8d1569685be86366f18ea89851db35 -
将发送至awk
:
$2 in a { # hash as array key
print "Match:" # separate hits in output
print a[$2], $1 # print matching dirscompared to
next # next record
}
a[$2]=$1 {next} # only first match is stored and
测试目录结构:
$ mkdir -p test/foo; mkdir -p test/bar/foo; touch test/foo/test; touch test/bar/foo/test
$ find test/
test/
test/bar
test/bar/foo
test/bar/foo/test # touch test
test/foo
test/foo/test # touch test