Win*_*nix 8 performance command-line search grep
grep 命令选项我想在我的整个驱动器中搜索一个字符串。按照我使用的Stack Overflow 中接受的答案:
sudo time grep -rnw '/' -e 'Sony 50"'
Run Code Online (Sandbox Code Playgroud)
在最快的 PCIe NVMe M.2 SSD 之一上处理 20 GB 数据需要53 小时;三星 Pro 960。
grep 输出日志在grep处理某些文件时,它会生成错误消息。这些可以通过附加2>/dev/null到命令来抑制。然而,这些错误会反馈正在取得的进展。一些示例输出(它不会全部适合)如下:
Binary file /home/Me/.config/google-chrome/Default/Sync Data/SyncData.sqlite3 matches
grep: /sys/kernel/security/ima/policy: Permission denied
grep: /sys/kernel/slab/:dt-0000008/alloc_calls: Function not implemented
grep: /sys/kernel/slab/:dt-0000008/free_calls: Function not implemented
(... SNIP ... 12 hours later PID 882 processed below...)
grep: /proc/882/task/922/attr/sockcreate: Invalid argument
grep: /proc/882/task/923/mem: Input/output error
(... SNIP ... 24 hours later PID 2954 below...)
grep: /proc/2598/attr/sockcreate: Invalid argument
grep: /proc/2954/task/2954/mem: Input/output error
(... SNIP ... 42 hours later PID 4396 below...)
grep: /proc/4389/attr/sockcreate: Invalid argument
grep: /proc/4396/task/4396/mem: Input/output error
(... SNIP ... After 53 hours `grep` finally finishes...)
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
97355.34user 83223.12system 53:07:40elapsed 94%CPU (0avgtext+0avgdata 31116maxresident)k
593910020inputs+0outputs (1major+10731minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
grep 给人的印象是它被冻结了有时我以为grep是卡住了,因为屏幕一个小时没有更新,硬盘灯也不怎么闪。然而,Conky 告诉我它仍在运行并在单核上占用 100% 的 CPU,如这个 GIF 所示。
在Linux (Ubuntu 16.04.3 LTS) 分区上使用的 43.8 GiB 中的19.5 GiB 中,内核使用了该空间的一半,即10 GB。下载和测试内核是我的消遣。
这个测试花了我周末和周一的大部分时间来完成。
我怎样才能加快速度grep并仍然得到我正在寻找的东西?
Win*_*nix 16
查看示例输出日志,我们看到搜索中包含虚拟文件系统,这是不必要的时间浪费。使用--exclude-dir选项从搜索中删除这些和其他目录。例如:
sudo time grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e 'Sony 50"'
Run Code Online (Sandbox Code Playgroud)
当grep解析/proc目录链被白白看着所有的进程的ID这需要一天以上的时间在我的情况。
此外,在处理时,/mnt它会不必要地查看已安装的 Windows NTFS 驱动器和 USB。
/media 包含 CD/DVD 驱动器和外部 USB 驱动器。
$ sudo time grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e 'Sony 50"'
Binary file /home/Me/.config/google-chrome/Default/Sync Data/SyncData.sqlite3 matches
11.35user 13.83system 0:56.35elapsed 44%CPU (0avgtext+0avgdata 8480maxresident)k
17369032inputs+0outputs (0major+1620minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
那里是56 秒而不是50 小时!
请注意,如果您usr从搜索中排除(在我的情况下包含 6.5 GB 的文件),则只需 8 秒:
4.48user 1.80system 0:08.75elapsed 71%CPU (0avgtext+0avgdata 6012maxresident)k
13008964inputs+0outputs (0major+1180minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
将系统目录排除在外似乎可以grep更好地跟踪,并且它永远不会在单核上达到 100% CPU。加上硬盘灯不断闪烁,所以你知道grep它真的在工作,而不是“在圈子里思考”。
如果您没有前缀tmp,/那么它将忽略任何包含tmp例如/home/Me/tmp. 如果您使用 --exclude-dir/tmp则将/home/Me/tmp搜索您的目录。
另一方面,如果您sys使用/then前缀,则会/sys搜索目录并报告错误。对于 也是如此/proc。所以你必须使用sys,proc而不是前缀/. 我测试的其他系统目录也是如此。
grepall考虑在 in 中设置别名,~/.bashrc这样您就不必--exclude-dir每次都键入参数列表:
alias grepall="grep --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var}"
Run Code Online (Sandbox Code Playgroud)
本节细分了通过将目录增量添加到--exclude-dir参数列表中节省了多少时间:
/proc并/sys节省52 小时/media节省3 分钟/mnt节省21 分钟/usr/src(通过指定src)节省53 秒/lib/modules(通过指定modules)节省39 秒/proc和/sys目录该/proc和/sys目录是最耗时,最无用的搜索和生成的大多数错误。这是“无用的”,因为这两个目录是在运行时动态创建的,并且不包含您想要的永久文件grep。
通过排除它们可以节省大量时间:
$ sudo time grep -rnw --exclude-dir={proc,sys} '/' -e 'Garbage 098jfsd'
/var/log/auth.log:4653:Feb 16 17:46:20 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys / -e Garbage 098jfsd
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /media/rick/S3A6550D005/hiberfil.sys: Input/output error
(... SNIP ...)
grep: /media/rick/S3A6550D005/winproductkey: Input/output error
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
422.43user 112.91system 26:59.03elapsed 33%CPU (0avgtext+0avgdata 31152maxresident)k
379671064inputs+0outputs (1major+10738minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
这次只用了27 分钟,节省了超过52 小时!
不过还是有错误。在/var目录中,这也是运行时创建的“虚拟目录”。在/run其中包含一个Android手机和目录/media包含现在连接到USB外部硬盘盒旧破碎笔记本硬盘目录。
/media到排除列表该/media目录包含一个通过 USB 3.0 端口连接的旧笔记本电脑驱动器。Smartctl 每天报告驱动器上的错误并且没有我们要查找的文件。我们将排除它以节省时间并减少错误消息:
$ sudo time grep -rnw --exclude-dir={proc,sys,media} '/' -e 'Garbage 654asdf'
/var/log/auth.log:4664:Feb 16 18:26:27 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media / -e Garbage 654asdf
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
405.51user 105.38system 23:26.89elapsed 36%CPU (0avgtext+0avgdata 30908maxresident)k
365800875inputs+0outputs (0major+10961minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
排除通过 USB 3.0 外壳连接的故障硬盘仅节省了 3 分钟,但减少了错误消息。
/mnt(Windows NTFS 分区)以排除列表该/mnt目录包含:
C:和E:)D:硬盘上的一个 NTFS Windows 10 分区 ( ) 具有 42 GiB 数据在 Windows 中没有任何兴趣,因此我们将排除/mnt以节省时间:
$ ll /mnt
total 44
drwxr-xr-x 5 root root 4096 Nov 12 07:19 ./
drwxr-xr-x 27 root root 4096 Feb 15 20:43 ../
drwxrwxrwx 1 root root 8192 Dec 30 14:00 c/
drwxrwxrwx 1 root root 8192 Dec 30 14:31 d/
drwxrwxrwx 1 root root 20480 Jan 1 13:22 e/
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt} '/' -e 'Garbage zx5cv7er'
/var/log/auth.log:5093:Feb 17 10:31:44 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt / -e Garbage zx5cv7er
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
51.50user 23.28system 2:08.85elapsed 58%CPU (0avgtext+0avgdata 15800maxresident)k
39866258inputs+0outputs (0major+6059minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
现在grep只需要 2 分 8 秒。通过排除具有 147 Gib 程序和数据的 Windows 10 分区可节省 21.5 分钟!
/usr/srcLinux 标头以排除列表该/usr/src目录包含 Linux Headers 源代码。就我而言,手动安装了 20 多个内核,这需要相当大的空间。虽然使用的参数是指定目录src:
$ du -h -s /usr/src
3.2G /usr/src
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt,src} '/' -e 'Garbage z5cv7er'
/var/log/auth.log:5096:Feb 17 10:34:28 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt --exclude-dir=src / -e Garbage z5cv7er
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
44.21user 8.54system 1:15.51elapsed 69%CPU (0avgtext+0avgdata 15864maxresident)k
33754180inputs+0outputs (0major+6062minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
现在 grep 只需要 1 分 15 秒。/usr/src通过src在--exclude-dir列表上指定来排除可节省 53 秒。
/lib/modules内核模块以排除列表该/lib/modules目录包含已编译的内核模块。虽然使用的参数是指定目录modules:
$ du -h -d1 /lib/modules
285M /lib/modules/4.14.18-041418-generic
282M /lib/modules/4.14.14-041414-generic
(... SNIP ...)
228M /lib/modules/4.9.76-040976-generic
6.0G /lib/modules
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt,src,modules} '/' -e 'Garbage 1cv7fer'
/var/log/auth.log:5117:Feb 17 11:07:41 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt --exclude-dir=src --exclude-dir=modules / -e Garbage 1cv7fer
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
19.22user 5.84system 0:35.61elapsed 70%CPU (0avgtext+0avgdata 15600maxresident)k
22111388inputs+0outputs (0major+6059minor)pagefaults 0swaps
Run Code Online (Sandbox Code Playgroud)
通过跳过 6 GB 的内核模块,我们的grep时间是 36 秒。/lib/modules通过modules在--exclude-dir参数中指定来添加可节省 39 秒。
其他目录的汇总列表: