我是 shell 脚本的新手,如果我能在以下问题上得到一些帮助,那就太好了。
我在 ~/home/dir
目录下有数千个文件夹/子文件夹和文件,并且一直在添加新文件。 (不幸的是,添加新文件的时间是随机的)。
在此文件夹中,我只想对已添加的新文件进行 grep。为了知道哪个文件是新文件,哪个文件是旧文件,我将之前的 grep 操作存储了我已经 grep 到目录 中名为
.path.txt
的 txt 文件中的文件的路径名~/home
例如在 path.txt 文件中,我有这样的东西
/home/dir/b1/file50.txt
/home/dir/abc/file52.txt
/home/dir/det/file539.txt
/home/dir/br/com_file6551.txt
/home/dir/n12/d2/c_file251.txt
/home/dir/fg/file51.txt
etc etc..
有什么方法可以将 path.txt
文件中的路径名作为输入传递给 grep,这样如果文件路径名已经存在,它就会跳过对该文件的 grep 处理。
或者有没有其他更简单的方法来跳过 grep 这些旧文件?
最佳答案
Barmar 的建议通常比 grep
快正在处理所有文件。 path.txt
中的路径越多, 加速越大。
我要补充一点:使用 find -print0 | fgrep -v -x -f
过滤行不通,那么过滤后如何处理路径中的空格? (xargs -I{} grep <pattern> "{}"
会起作用,但会慢两个数量级。)
find /home/dir -type f |
fgrep -v -x -f path.txt |
tr '\n' '\0' |
xargs -0 grep '<pattern>'
测试设置:21997 个文件,每个约 20k,一些路径中有空格。我多次运行每个命令并使用最快的时间来控制磁盘缓存。
grep -R asd * 0.302s
find * -type f -print0 | xargs -0 grep asd 0.325s
find * -type f |
fgrep -v -x -f ../5000paths.lst | 0.228s
tr '\n' '\0' |
xargs -0 grep asd
find * -type f |
fgrep -v -x -f ../10000paths.lst | 0.269s
...
find * -type f |
fgrep -v -x -f ../15000paths.lst | 0.189s
...
find * -type f |
fgrep -v -x -f ../20000paths.lst | 0.094s
...
find * -type f |
fgrep -v -x -f ../all21997paths.lst | 0.059s
...
关于Linux:如果文件路径名已存在于输入文件中,则跳过 grepping 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40158995/