find
因此,我使用和的組合grep
從純文字文件中過濾出文件名列表。
這是我運行的命令:
find /Volumes/Documents\ -\ Part\ 1/July 2009 -type f | grep -vf files.txt
在 files.txt 我有這個:
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
我希望它輸出任何不匹配的行,但我得到的是:
grep: invalid character range
這是什麼原因呢? files.txt 還有很多內容,我只是省略了它,因為它太長了。我那裡也有幾個 unicode 字元。這會引起任何問題嗎?
Mac OS X Yosemite、bash 3.2.57(1)-release、grep (BSD grep) 2.5.1-FreeBSD
答案1
太長了;添加-F
grep選項-f
用於引用包含以下內容清單的文件圖案- 您的檔案不包含模式列表,它包含檔案名稱列表
人 grep
-f FILE, --file=FILE 從 FILE 取得模式,每行一個。空文件包含零個模式,因此不符合任何內容。 (-f 由 POSIX 指定。)
您需要確保檔案名稱中的任何元字元都被轉義,除非您希望將它們視為元字元。
$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
$ echo a | grep -vf files.txt
a
在我看來,您的 files.txt 可能包含的內容不僅僅是您顯示的四行。
使用檢查文件
$ wc files.txt
4 21 221 files.txt
$ sum files.txt
43924 1
如果有疑問,請使用-F
選項(大寫 F) - 但這樣您就不會轉義 file.txt 中的元字元。
請注意以下事項
$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
[z-a]
$ echo aaa | grep -vf files.txt
grep: Invalid range end
$ echo aaa | grep -Fvf files.txt
aaa
該-F
選項告訴 grep 您的搜尋模式不包含正規表示式,並且應該將它們視為純文字。