2011-05-31 44 views
12

我正在Linux & bash(或Cygwin & bash)中工作。Unix find:stdin的文件列表

我有一個巨大的 - 巨大的 - 目錄結構,我必須在大海撈針中找到幾根針。

具體來說,我正在尋找這些文件(20個左右):

foo.c 
bar.h 
... 
quux.txt 

我知道,他們是在一個子目錄地方.下。

我知道我可以用 find . -name foo.c -print找到其中的任何一個。該命令需要幾分鐘才能執行。

如何使用完整的目錄名稱打印這些文件的名稱?我不想執行20個單獨的find s - 這將花費太長時間。

我可以給find標準文件列表嗎?從一個文件?有什麼不同的命令可以做我想要的嗎?

我必須首先使用循環或其他東西來組裝find-o的命令行嗎?

回答

11

如果你的目錄結構是巨大的,但不經常變化的,這是很好的運行

cd /to/root/of/the/files 
find . -type f -print > ../LIST_OF_FILES.txt #and sometimes handy the next one too 
find . -type d -print > ../LIST_OF_DIRS.txt 

後,你可以非常快找到任何(使用grep,sed的,等..),並更新文件 - 僅在樹被更改時列出。(這是一個簡單的替換,如果你沒有做locate

所以,

grep '/foo.c$' LIST_OF_FILES.txt #list all foo.c in the tree.. 

如果想找到的文件列表,你可以嘗試以下方法:

fgrep -f wanted_file_list.txt < LIST_OF_FILES.txt 

或直接與查找命令

find . type f -print | fgrep -f wanted_file_list.txt 

-f for fgrep mean - read patter ns,所以你可以很容易地輸入多個模式...

1
+0

一旦我保存在一個文件列表數組,使用循環來構建find命令?在這種情況下,最好的命令行是什麼? – JXG 2011-05-31 11:29:48

+0

您不需要將文件放入數組中;只需直接在數組中創建find命令然後調用它即可。 – 2011-05-31 11:38:04

+0

呃,你是怎麼做到的? – JXG 2011-05-31 11:54:51

3

您應該不需要運行find二十次。

您可以構建一個單一命令的文件名符的倍數:

find . \(-name 'file1' -o -name 'file2' -o -name 'file3' \) -exec echo {} \; 
+0

-exec echo {} \; 是沒有必要的。 – akond 2011-05-31 11:01:54

+0

是的,謝謝,但我習慣於一個非GNU版本的'find',所以我傾向於明確。如果'echo'被替換爲'printf',我們可以對輸出進行更多的控制。 – pavium 2011-05-31 11:16:38

+0

所以如果有20個這樣的文件是沒有別的辦法輸入'-o -name' 20次?這沒有利用來自stdin或文件的管道輸入。 – 2017-09-06 18:42:01

2

是對locate(1)命令可以接受的答案嗎?每晚它建立索引,你可以很快查詢索引:

$ time locate id_rsa 
/home/sarnold/.ssh/id_rsa 
/home/sarnold/.ssh/id_rsa.pub 

real 0m0.779s 
user 0m0.760s 
sys 0m0.010s 

我放棄了在36秒內我的主目錄執行類似find命令。 :)

如果每晚都不起作用,則可以在運行locate(1)查詢之前手動運行updatedb(8)程序。 /etc/updatedb.confupdatedb.conf(5))允許您選擇包含或排除的特定目錄或文件系統類型。

+0

原則上,我想要做的事情,並得到我想要的,我可以grep我所需的目錄,但每晚不起作用,我沒有'updatedb'的權限。 – JXG 2011-05-31 11:00:01

+0

@JXG,不要忽略聯機幫助中的'EXAMPLES'部分:) _要創建一個私有的mlocate數據庫,而不是根用戶,請運行'updatedb -l 0 -o db_file -U source_directory'。 – sarnold 2011-05-31 11:03:14

+0

哈哈,我的系統的聯機幫助中沒有該部分。 – JXG 2011-05-31 11:10:28

0

下面是一個處理來自stdin的文件列表並組裝你的(FreeBSD)find命令來使用擴展正則表達式匹配(n1|n2|n3)的方法。

對於GNU找到你可能需要使用下列選項之一啓用擴展的正則表達式匹配:

-regextype posix-egrep

-regextype posix-extended

echo ' 
foo\\.c 
bar\\.h 
quux\\.txt 
' | xargs bash -c ' 
IFS="|"; 
find -E "$PWD" -type f -regex "^.*/($*)$" -print 
echo find -E "$PWD" -type f -regex "^.*/($*)$" -print 
' arg0 

# note: "$*" uses the first character of the IFS variable as array item delimiter 
(
IFS='|' 
set -- 1 2 3 4 5 
echo "$*" # 1|2|3|4|5 
)