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)-发布,grep (BSD grep) 2.5.1-FreeBSD
答案1
TLDR;添加-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 您的搜索模式不包含正则表达式,并且它应该将它们视为纯文本。