考虑一下我将文件从一个磁盘(例如SD卡)复制到给定目录(例如/home/pepa/dir1)的情况但是后来在Dir1中创建了子目录,并且许多文件被移动到这些子目录。过了一段时间,我想清理SD,但我想首先确保SD中的所有文件确实存在于dir1或其任何子目录中。我如何检查SD中的所有文件确实存在于dir1或其任何子目录中?(通过终端中的命令行或特定的linux实用程序)
/home/pepa/dir1
g52tjvyc1#
假设文件数不太大:
#!/bin/bash sd=$1 dir1=$2 mkmap()( if cd "$1"; then find -type f -exec sha256sum {} + |\ sed 's/^\\//' fi ) awk ' NR==FNR { k=$1; sub(/^[^ ]* ./,""); a[k]=$0 ; next } { delete a[$1] } END { print "missing files:"; for(i in a) print a[i] } ' <(mkmap "$sd") <(mkmap "$dir1")
mkmap:
mkmap
sha256sum
sed
然后为每个目录树创建Map并馈送到awk:
awk
为清楚起见,省略了错误检查。对于数量极大的文件,可以生成两个列表,然后生成sort,并馈送到comm:
sort
comm
#!/bin/bash sd=$1 dir1=$2 mkmap()( if cd "$1"; then find -type f -exec sha256sum {} + |\ sed 's/^\\//' fi ) map2sums()( mkmap "$2" |\ tee "$1-map" |\ sed 's/ .*$//' |\ sort -u > "$1-sums" ) map2sums sd "$sd" map2sums dir1 "$dir1" comm -23 sd-sums dir1-sums |\ sed 's/^/^/' |\ grep -f - sd-map |\ sed 's/^[^ ]* .//' rm {sd,dir1}-{map,sums}
map2sums
创建校验和Map和列表。comm管道:
grep
然后清除临时文件。如果你想快点,
AND您只关心DIR1下是否存在与SD下的文件具有相同名称的文件(即,您不关心它们是否包含相同的内容)ANDSD下文件的基本名称是唯一的和没有太多的文件(即在内存中存储名称列表是可行的)
那么你可以试试这个替代版本:
#!/bin/bash sd=$1 dir1=$2 mklist()( cd "$1" && find -type f -print0 ) gawk -F/ -v RS='\0' ' NR==FNR { a[$NF]; next } { delete a[$NR] } END { for (i in a) print i } ' <(mklist "$sd") <(mklist "$dir1")
脚本可以处理任何法律的名称的文件,但如果名称中包含换行符,则输出将不明确。注意,与前两个版本不同,如果文件被重命名,这个版本将不会产生合理的输出。例如,给定以下操作序列:
cd /dir1 cp /sd/f1 . cp /sd/f2 . cp /ds/f3 . mv f1 f4 rm f2 mv f3 f2
这个版本将报告/sd/f1和/sd/f3丢失(并且认为/sd/f2存在),这可能不是所期望的。
/sd/f1
/sd/f3
/sd/f2
1条答案
按热度按时间g52tjvyc1#
假设文件数不太大:
mkmap
:sha256sum
来计算树中文件的校验和sed
删除sha256sum
添加的标记奇数文件名的指示符然后为每个目录树创建Map并馈送到
awk
:为清楚起见,省略了错误检查。
对于数量极大的文件,可以生成两个列表,然后生成
sort
,并馈送到comm
:map2sums
创建校验和Map和列表。
comm
管道:comm
输出仅存在于SD列表中的校验和sed
以将校验和转换为正则表达式grep
以在SDMap中查找正则表达式sed
从Map中剥离校验和并打印相关文件名然后清除临时文件。
如果你想快点,
AND您只关心DIR1下是否存在与SD下的文件具有相同名称的文件(即,您不关心它们是否包含相同的内容)
ANDSD下文件的基本名称是唯一的
和没有太多的文件(即在内存中存储名称列表是可行的)
那么你可以试试这个替代版本:
脚本可以处理任何法律的名称的文件,但如果名称中包含换行符,则输出将不明确。
注意,与前两个版本不同,如果文件被重命名,这个版本将不会产生合理的输出。例如,给定以下操作序列:
这个版本将报告
/sd/f1
和/sd/f3
丢失(并且认为/sd/f2
存在),这可能不是所期望的。