ls --颜色 | grep 不起作用

ls --颜色 | grep 不起作用

我正在尝试使用以下命令列出所有隐藏目录

ls -lhAF1 | grep -E '^d.*[0-9]{2}:[0-9]{2} \.'

效果很好

正则表达式的说明:我试图获取具有以下格式的所有行:d,然后是一些文本,然后是时间戳,然后是空格,然后是点,然后是更多文本

但是,当我尝试使用此命令为 ls 输出着色时:

ls --color -lhAF1 | grep -E '^d.*[0-9]{2}:[0-9]{2} \.'

它给出零结果,没有的输出--color是:

drwxr-xr-x 1 用户组 4096 二月 1 08:48 .invisible

为什么 ls / grep 会这样?

答案1

--color添加颜色的转义序列。如果将( 的 )输出重定向ls --color到文件,您可以看到这一点。

它看起来是这样的:

 drwxr-xr-x  6 root root 4.0K Jan  9 08:23 ^[[01;34m.cabal^[[0m/

为了解决这个问题,请尝试以下操作:

 ls -lhAF1 --color | grep -E '^d.*[0-9]{2}:[0-9]{2} .*\.'

答案2

解析ls通常是个坏主意。经常,但是不总是。这是给您的另一个建议,它将所需的目录收集在一起,然后将集合传递给ls.

find .* -maxdepth 0 -type d \( -name '.[^.]' -o -name '.??*' \) -exec ls -ld --color=always {} +

有人指出,原始代码实际上将目录列表限制为过去六个月内修改过的目录。这可以通过以下替代解决方案来处理。

find .* -maxdepth 0 -type d -mtime -180 -mtime +0 \( -name '.[^.]' -o -name '.??*' \) -exec ls -ld --color=always {} +

与以往一样,如果您find不理解尾随,+请将其替换为\;以牺牲效率为代价。

答案3

原因是ls即使它连接到终端,它的输出也总是着色的。从man ls

   --color[=WHEN]
          colorize the output.   WHEN  defaults  to  'always'  or  can  be
          'never' or 'auto'.  More info below

许多其他工具,例如grep当标准输出为终端时不会保留颜色,但由于某些原因ls被设计为不同的行为。着色输出是通过使用实现的ANSI 转义码由您的终端解释。将输出重定向ls到文件并在编辑器中打开它:

$ ls --color  -lhaF1  > /tmp/RESULT
$ less /tmp/RESULT
total 12K
drwxr-xr-x  3 ja   users 4.0K Feb  2 09:47 ESC[0mESC[01;34m.ESC[0m/
drwxrwxrwt 12 root root  4.0K Feb  2 09:51 ESC[30;42m..ESC[0m/
drwxr-xr-x  2 ja   users 4.0K Feb  2 09:47 ESC[01;34m.invisibleESC[0m/
-rw-r--r--  1 ja   users    0 Feb  2 08:35 a|a

如果您$LESS设置了变量,则可能需要在运行之前取消设置它less,以便查看原始转义码而不是颜色。所以,总结一下,当使用--colorgets的时候grep,得到的并不是你所看到的,而是一堆与之一起的转义码。要修复它,要么--colors根本不使用,要么将其设置为--auto

$ ls --color=auto -lhaF1 | grep  -E '^d.*[0-9]{2}:[0-9]{2} \.'

答案4

我宁愿过滤传递给 的文件列表,而不是应用于无论如何都无法可靠地进行后处理grep的输出,例如:lsls

ls -lFhd --color -- .*(/)

zsh。或者,正如您自己的方法所示,您只需要 6 个月前到现在最后修改的目录,而不是具有特殊权限的目录:

ls -lFhd --color -- .*(/mM-6mM+0f-7000)

相关内容