如果
filelist.txt每行只有一个文件名:
find /dir | grep -f <(sed 's@^@/@; s/$/$/; s/([.[*]|])/\1/g' filelist.txt)
(该
-f选项意味着grep搜索给定文件中的所有模式。)
的说明<(sed 's@^@/@; s/$/$/; s/([.[*]|])/\1/g' filelist.txt)
:
在
<( ... )被称为过程subsitution,并且有点类似
$( ... )。这种情况是等效的(但是使用流程替换更整洁,可能更快一些):
sed 's@^@/@; s/$/$/; s/([.[*]|])/\1/g' filelist.txt > processed_filelist.txtfind /dir | grep -f processed_filelist.txt
调用
sed运行命令
s@^@/@,
s/$/$/并
s/([.[*]|])/\1/g在命令的每一行上将其
filelist.txt打印出来。这些命令将文件名转换为与grep更好地兼容的格式。
s@^@/@
表示/
在每个文件名之前放置一个。(^
在正则表达式中表示“行首”)s/$/$/
表示$
在每个文件名的末尾放置a 。(第一个$
表示“行尾”,第二个只是字面量$
,然后由grep解释为“行尾”)。
这两个规则的结合意味着grep将只寻找像
.../<filename>这样的匹配,因此
a.txt不匹配
./a.txt.backup或
./abba.txt。
s/([.[*]|])/\1/g``在每次出现
.
[
]或之前放置一个
*。Grep使用正则表达式,这些字符被认为是特殊字符,但我们希望它们是普通字符,因此我们需要对其进行转义(如果不对它们进行转义,则文件名
a.txt将会与匹配
abtxt)。
举个例子:
$ cat filelist.txtfile1.txtfile2.txtblah[2012].txtblah[2011].txtlastfile$ sed 's@^@/@; s/$/$/; s/([.[*]|])/\1/g' filelist.txt/file1.txt$/file2.txt$/blah[2012].txt$/blah[2011].txt$/lastfile$
然后,Grep在搜索的输出时会将输出的每一行用作模式
find。



