2012-01-20 57 views
2

我一直在寻找一种方法来列出需要存在的文件列表中不存在的文件。这些文件可以存在于多个位置。我现在拥有的一切:Bash脚本来列出找不到的文件

#!/bin/bash 
fileslist="$1" 
while read fn 
do 
    if [ ! -f `find . -type f -name $fn ` ]; 
    then 
    echo $fn 
    fi 
done < $fileslist 

如果文件不存在find命令不会打印任何东西,测试不起作用。删除not并创建if then else条件不能解决问题。

如何打印从文件名列表中找不到的文件名?

新的脚本:

#!/bin/bash 
fileslist="$1" 
foundfiles="~/tmp/tmp`date +%Y%m%d%H%M%S`.txt" 
touch $foundfiles 
while read fn 
do 
    `find . -type f -name $fn | sed 's:./.*/::' >> $foundfiles` 
done < $fileslist 
cat $fileslist $foundfiles | sort | uniq -u 
rm $foundfiles 
+0

被分离发现你可以和与列表差异,你期待什么? – cdeszaq

+0

@cdeszaq,我想到的第一件事,但不能拿出没有临时文件或纯粹bashisms做到这一点:) –

+0

目前我创建了一个列表,我可以找到并与文件列表不同。我认为我可以自动化这些创建我必须处理的文件列表。 – user1161495

回答

1

尝试用[[ -z "$(find . -type f -name $fn)" ]] && echo $fn更换身体。 (请注意,这段代码必然会在包含空格的文件名中出现问题)。

更高效bashism:

diff <(sort $fileslist|uniq) <(find . -type f -printf %f\\n|sort|uniq) 

我认为你可以处理diff的输出。

+0

既不-z也不! -n与查找结果一起使用,当它与文件名不匹配时。 – user1161495

+0

适用于我'$ [[-z“$(find/tmp -name nosuchfile)”]] &&回声没有这样的东西在那里 没有这样的东西在那里' –

+0

我已经添加了更有效的差异。既然你现在有差异,我认为你可以适当调整差异选项,并知道如何处理输出 –

1

这里是test.bash:

#!/bin/bash 

fn=test.bash 

exists=`find . -type f -name $fn` 
if [ -n "$exists" ] 
then 
    echo Found it 
fi 

它设置$ =存在对发现的结果。 if -n检查结果是否不为空。

+0

如果$ exists为null,那么在'if'语句中会出现语法错误。 – schtever

+0

我用一个存在的文件测试了这个代码,一个没有。它运行良好。 – Almo

+0

既不-z也不! -n与查找结果一起使用,当它与文件名不匹配时。 – user1161495

1
#!/bin/bash 
fileslist="$1" 
while read fn 
do 
    FPATH=`find . -type f -name $fn` 
    if [ "$FPATH." = "." ] 
    then 
    echo $fn 
    fi 
done < $fileslist 

你就近了!

+0

这引发了当找不到匹配项时找到回报的问题。我如何评估结果? – user1161495

+0

'find'的退出代码失败时将为false。所以你可以简单地找到。 -name“$ fn”>/dev/null ||回声没有:“$ fn”' – tripleee

0

重复的find一次过滤一个文件非常昂贵。如果你的文件列表是从find输出直接兼容,运行单个find并从列表中删除任何匹配:

find . -type f | 
fgrep -vxf - "$1" 

如果没有,也许你可以从find在管道按摩输出fgrep如此前它与您的文件中的格式相匹配;或者相反,将文件中的数据按摩到find兼容。

+0

我正在寻找20或100个文件,但目录结构,我正在寻找有近1500个文件。我认为这不会起作用。 – user1161495

1

试试这个:

find -type f -print0 | grep -Fzxvf - requiredfiles.txt 

-print0-z防止其包含换行符的文件名。如果您的实用程序没有这些选项,并且您的文件名不包含换行符,那么您应该没问题。

+0

我喜欢这个主意,但我不认为-v选项可以像那样工作。 – marinara

+0

得到了这个工作很好,将带有一个bash循环和grep -Fzqa。 10K文件也很快 – marinara

0

我使用这个脚本和它的作品对我来说

#!/bin/bash 
fileslist="$1" 
found="Found:" 
notfound="Not found:" 
len=`cat $1 | wc -l` 
n=0; 

while read fn 
do 
    # don't worry about this, i use it to display the file list progress 
    n=$((n + 1)) 
    echo -en "\rLooking $(echo "scale=0; $n * 100/$len" | bc)% " 
    if [ $(find/-name $fn | wc -l) -gt 0 ] 
    then 
    found=$(printf "$found\n\t$fn") 
    else 
    notfound=$(printf "$notfound\n\t$fn") 
    fi 
done < $fileslist 

printf "\n$found\n$notfound\n" 

行计数的行数,如果该值大于0的发现是成功的。这搜索硬盘上的所有内容。你可以用/替换。仅用于当前目录。

$(find/-name $fn | wc -l) -gt 0 

然后,我只是在文件列表中的文件运行由换行符

./search.sh files.list