Alo*_*dal 6 command-line shell grep dot-files
有时我需要在未知的点文件中找到罪魁祸首,而不是试图找出应该归咎于哪个包(例如 xfce4 或 thunar?)以及它们的命名约定是什么(.app vs .application vs .some_old_name vs .config/app...),我只想快速而肮脏的方式:
me@here:~$ grep -IR .* -e culprit
Run Code Online (Sandbox Code Playgroud)
但这种快速而肮脏的方式也是愚蠢的方式。几分钟后,我明白这也.*
意味着..
,我们就这样了。有时我会求助于可能更快更脏的变体:
me@here:~$ grep -IR /home/me -e culprit
Run Code Online (Sandbox Code Playgroud)
结果证明这是一种非常愚蠢的行为,特别是如果我对mount
我的$HOME
. 太糟糕了,我无法找出快速、干净和正确的方法。(而且我的磁头正在慢慢磨损。)
是否有可能在通配符扩展中实现这一点?即.*
不匹配..
(和../..
...)的变体?
如果你在 Linux 上,你可以试试
grep -IR --exclude-dir=".." culprit .*
Run Code Online (Sandbox Code Playgroud)
既然您询问了 shell 通配符,我的第一个想法是.[!.]* ..[!.]*
,如
grep -IR culprit .[!.]* ..[!.]*
Run Code Online (Sandbox Code Playgroud)
grep
如果没有以..
.开头的文件,则会出现错误退出的问题。要解决这个问题,你可以添加-s
到grep
告诉它忽略丢失的文件:
grep -IRs culprit .[!.]* ..[!.]*
Run Code Online (Sandbox Code Playgroud)
或者,如果没有以开头的文件,则使用bash
andzsh
nullglob
选项使..[!.]*
扩展为零..
shopt -s nullglob # for bash
setopt nullglob # for zsh
grep -IR culprit .[!.]* ..[!.]*
Run Code Online (Sandbox Code Playgroud)
以上所有失败,总会有 find
find . -path "./.*" -exec grep culprit {} +
Run Code Online (Sandbox Code Playgroud)
如果您有可用的 bash,则可以使用extglob
来仅获取点文件。
shopt -s extglob
grep -IR 'foo' .!(|.)
Run Code Online (Sandbox Code Playgroud)
!
扩展 glob 中的运算符是“not”。此模式匹配以点开头的任何内容,不包括'.'
和'..'
。
感谢这个wiki,我发现有这个GLOBIGNORE
变量:
Bash 变量(不是 shopt)GLOBIGNORE 允许您指定 glob 不应匹配的模式。这可以让您解决臭名昭著的“我想匹配所有点文件,但不是 . 或 ..”问题:
Run Code Online (Sandbox Code Playgroud)$ echo .* . .. .bash_history .bash_logout .bashrc .inputrc .vimrc $ GLOBIGNORE=.:.. $ echo .* .bash_history .bash_logout .bashrc .inputrc .vimrc
好的一点是,这几乎没有副作用(我的意思是,您真正想要匹配..
and 的频率是多少?),因此from.
甚至可以接受,并且对于手动任务,只需使用旧的glob,如第一个示例所示Q。export GLOBIGNORE=.:..
.bashrc
.*
me@here:~$ set | grep GLOBIGNORE
GLOBIGNORE=.:.
me@here:~$ grep -IR .* -e culprit
.some-app/config: set culprit=1
me@here:~$
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9120 次 |
最近记录: |