我想在Linux的find
命令中使用正則表達式來遞歸地跳入一個龐大的目錄樹,向我展示所有的.c,.cpp和.h文件,但省略了包含某些子字符串的匹配。最終,我想將輸出發送到一個xargs
命令,以對所有匹配的文件執行特定處理。我可以通過grep管道輸出find
以刪除包含這些子字符串的匹配項,但該解決方案對於包含空格的文件名不起作用。所以我嘗試使用find
的-print0選項,它終止每個文件名用一個nul字符而不是一個換行符(空白),並使用xargs -0
來期望nul-delimited輸入,而不是空格分隔的輸入,但我無法弄清楚如何通過管道grep過濾器成功地通過nul-delimited find
; grep -Z在這方面似乎沒有幫助。如何從Linux的「find」命令的輸出中排除匹配某些模式的目錄?
所以我想我只是寫一個更好的正則表達式爲find
,並取消中間grep
過濾器...也許sed
將是一個替代?
在任何情況下,對目錄的以下的小採樣...
./barney/generated/bam bam.h
./barney/src/bam bam.cpp
./barney/deploy/bam bam.h
./barney/inc/bam bam.h
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
...我要輸出到包括所有的.H,.C,和.cpp文件,但不是那些那些出現在'生成'和'部署'目錄中的。
順便說一句,你可以通過切割&粘貼在此整條生產線到您的bash shell創建用於測試的解決方案,這個問題整個測試目錄(名爲fredbarney):
mkdir fredbarney; cd fredbarney; mkdir fred; cd fred; mkdir inc; mkdir docs; mkdir generated; mkdir deploy; mkdir src; echo x > inc/dino.h; echo x > docs/info.docx; echo x > generated/dino.h; echo x > deploy/dino.h; echo x > src/dino.cpp; cd ..; mkdir barney; cd barney; mkdir inc; mkdir docs; mkdir generated; mkdir deploy; mkdir src; echo x > 'inc/bam bam.h'; echo x > 'docs/info info.docx'; echo x > 'generated/bam bam.h'; echo x > 'deploy/bam bam.h'; echo x > 'src/bam bam.cpp'; cd ..;
這個命令在所有的.H ,.C,和.cpp文件...
find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$"
...但如果我管其通過xargs的輸出時,「咣噹咣噹」文件分別獲得視爲兩個獨立的(不存在的)的文件名(注意這裏我只是簡單地使用ls
作爲我交流的替身tually要與輸出做):
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" | xargs -n 1 ls
ls: ./barney/generated/bam: No such file or directory
ls: bam.h: No such file or directory
ls: ./barney/src/bam: No such file or directory
ls: bam.cpp: No such file or directory
ls: ./barney/deploy/bam: No such file or directory
ls: bam.h: No such file or directory
ls: ./barney/inc/bam: No such file or directory
ls: bam.h: No such file or directory
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
所以我可以提高,與-print0和-0參數傳遞給find
和xargs
:
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" -print0 | xargs -0 -n 1 ls
./barney/generated/bam bam.h
./barney/src/bam bam.cpp
./barney/deploy/bam bam.h
./barney/inc/bam bam.h
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
...這是偉大的,但我不希望輸出中的「生成」和「部署」目錄。所以我試試這個:
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" -print0 | grep -v generated | grep -v deploy | xargs -0 -n 1 ls
barney fred
......這顯然不起作用。所以我嘗試使用-Z選項和grep(不知道-Z選項到底是什麼),那也不管用。所以,我想我會寫一個更好的正則表達式find
,這是我能想出的最好:
find . -regextype posix-egrep -regex "(?!.*(generated|deploy).*$)(.+\.(c|cpp|h)$)" -print0 | xargs -0 -n 1 ls
...但慶典不喜歡這樣(*:!未找到事件,無論這意味着),即使這不是一個問題,我的正則表達式似乎沒有在我通常使用的正則表達式測試器網頁上工作。
任何想法,我可以使這項工作?這是我想要的輸出:
$ find . [----options here----] | [----maybe grep or sed----] | xargs -0 -n 1 ls
./barney/src/bam bam.cpp
./barney/inc/bam bam.h
./fred/src/dino.cpp
./fred/inc/dino.h
...我想避免腳本&臨時文件,我想可能是我唯一的選擇。
在此先感謝! 馬克
'未找到事件'是因爲'!'被解釋爲'bash'的歷史擴展請求。單引號出現在其中的字符串,或給它一個額外的轉義。我建議單引號! – Sorpigal 2012-07-12 16:27:47