如果
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'