2012-01-20 56 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