如何从“ls -R”输出中排除目录?

如何从“ls -R”输出中排除目录?

如果

ls -aR | grep ":$"

回报

./.hiddendir2:
./dir1:
./dir3:
./dir3/.hiddendir4:

那么你如何更新给 grep 的模式,以便你只得到

./dir1:
./dir3:

(请注意,包含 .hiddendir4 的最后一行被省略,即使它的父级未被隐藏)


这是同一问题的冗长版本,带有一些上下文:

我在以下位置找到了一个很棒的脚本http://www.centerkey.com/tree/用于打印目录树,但输出有时会被我正在处理的存储库的 .git 目录的后代弄乱。

如果我正确地阅读了源代码,我需要更改这一行的 grep 的模式:

ls -aR | grep ":$"

到目前为止,我想出了^\./(?!\.)\w+:$在测试中似乎有效的方法http://regexpal.com/,但是当我尝试在 bash 中运行时就崩溃了。我怀疑(1)我使用的正则表达式测试工具之间的差异与 grep 如何解析模式,(2)bash 转义字符要求和(3)模式设计的组合都需要解决才能解决这个问题。在我最终在这方面花费太长时间之前,感谢您的帮助。

答案1

您确实应该使用file比“ls -l”为您提供的内容对目录内容进行更深入的询问。

find . -type f

find命令是古老的 Unix 魔法。它将使您免于无休止的正则表达式争论。

答案2

既然您正在寻找打印目录树的东西,为什么不直接使用 Steve Baker 的呢tree? (这是大多数发行版在其存储库中包含的一个。)

您应该看一下它的联机帮助页,但这可能会帮助您入门:

tree -a -I '.git'

(包括点文件/-dirs,排除包含“.git”的所有内容)

答案3

您发布的第一个命令无法给出您显示的结果,因为它们末尾没有冒号;大概是你把它们脱掉了。您引用的脚本执行此操作来选择目录路径,该路径ls -R显示时附加了冒号,但没有什么可以阻止文件名和路径以冒号结尾并给出误报。这也会让你的标题产生误导;您想保留大多数目录并仅排除少数目录。

问题如下: 正则表达式有几种不同的“风格”(标准),大多数相似,但在细节上有重要差异。在 Unix 和 Unix 起源的软件中有两种常见的,称为基本正则表达式(BRE)和扩展正则表达式(ERE)。大多数 shell(和标准查找)中使用一种更简单的形式来匹配文件名(和大小写选择)(仅 ? * 和 [...]),它甚至不称为 regexp,只是模式。 Perl 定义了一种更扩展的形式,但可以在外部使用,称为 Perl 兼容正则表达式 (PCRE)。看为什么我的正则表达式在 X 中有效但在 Y 中无效?http://en.wikipedia.org/wiki/Regular_Expression

您的(?!“前瞻”仅在 PCRE 中,而标准grep默认情况下执行 BRE 或带有 ERE -E,尽管似乎某些版本grep可以执行 PCRE 或者您可以获取并安装单独的pcregrep.但你不需要它。如果您想要 curr dir 的非隐藏子级,只需执行'^\./\w'或 ,'^\./[^.]'具体取决于您想要的严格程度。但是你说你不希望路径中的任何位置都存在隐藏目录,这对于正则表达式来说更难做到,而对于像 之类的负匹配则更容易做到grep -v '/\.'

反斜杠在 bash(以及大多数(如果不是全部)shell)和 grep(BRE 或 ERE)中都很特殊,因此它们必须是双引号\\或单引号;我更喜欢后者。请注意,此处双引号是不够的。

更好的方法: 您实际上只需要目录路径,因此其他答案所建议的find -type d | grep -v /\.是更好的方法。这不会浪费时间列出您随后丢弃的普通文件名。或者,您也可以不使用;ls -R | grep :$来使用。-a默认情况下ls已经跳过隐藏条目(普通文件和目录)。正如您引用的脚本所做的那样!

答案4

扩展 @dan-garthwaite 所说的内容,find通常是搜索目录树时使用的工具。一般语法是:

find /path/to/search [one or more expressions]

请参阅手册页了解所有可能的表达式,但一些方便的表达式是:

-type x         # Where x = f for files, d for directories, s for sockets, etc.
-mtime x        # Where x = number of minutes since the file was last accessed
-name pattern   # Where pattern = a string to search for (use * for wildcard match)
-iname pattern  # Same as -name, but case insensitive
-size x         # Where x = size, human readable (eg. 500k, 20m, ...)
-user name      # Where name = owner of file

例如,要在 /home 中搜索 bob 拥有且大于 5MB 的所有 jpg 文件,您可以运行:

find /home -user bob -size +5m -iname '*.jpg'

相关内容