4

我正在尝试列出名称仅包含大写字母的目录中的所有条目。目录需要附加“/”。

#!/bin/bash
cd ~/testfiles/
ls | grep -r *.*

由于 grep 默认只查找大写字母(对吗?),我只是递归地在 testfiles 下的目录中搜索所有只包含大写字母的名称。

不幸的是,这不起作用。

至于附加目录,我不确定为什么需要这样做。有谁知道我可以从哪里开始详细解释我可以用 grep 做什么?此外如何解决我的问题?

4

3 回答 3

1

不,grep 不仅考虑大写字母。

你的问题我有点不清楚,例如:

  • 从您对 -r 选项的使用来看,您似乎想要递归搜索,但是您没有这么说。为简单起见,我假设您不需要;如果您需要递归,请考虑查看@twm 的答案。
  • 您只想查找大写字母(字母)。这是否意味着您不想接受任何其他(非字母)字符,但它们对文件名有效(如数字或破折号、点等)
  • 因为你没有说我不允许每行只有一个文件,我假设它是好的(因此使用ls -1)。

天真的解决方案是:

ls -1 | grep "^[[:upper:]]\+$"

也就是说,打印所有只包含大写字母的行。在我打印的 TEMP 目录中,例如:

ALLBIG
LCFEM
WPDNSE

但是,这将排除像README.TXTor之类的文件FILE001,根据您的要求(见上文)最有可能包含这些文件。

因此,更好的解决方案是:

ls -1 | grep -v "[[:lower:]]\+"

也就是说,打印所有不包含小写字母的行。在我打印的 TEMP 目录中,例如:

ALLBIG
ALLBIG-01.TXT
ALLBIG005.TXT
CRX_75DAF8CB7768
LCFEM
WPDNSE
~DFA0214428CD719AF6.TMP

最后,要“正确标记”带有尾随 '/' 的目录,您可以使用-F(or --classify) 选项。

ls -1F | grep -v "[[:lower:]]\+"

同样,示例输出:

ALLBIG
ALLBIG-01.TXT
ALLBIG005.TXT
CRX_75DAF8CB7768
LCFEM/
WPDNSE/
~DFA0214428CD719AF6.TMP

请注意find,如果您可以使用不同的输出(例如find ! -regex ".*[a-z].*"),则将使用不同的选项,但这将具有不同的输出。

于 2013-02-05T19:51:58.607 回答
0

确切的正则表达式取决于 ls 命令的输出格式。假设你不使用 ls 的别名,你可以试试这个:

ls -R  | grep -o -w "[A-Z]*"

请注意,使用-Rin ls 您将递归列出当前目录下的目录和文件。grep 选项-o告诉 grep 只打印文本的匹配部分。这些-w选项告诉 grep 只考虑整个单词的匹配。这"[A-Z]*"是一个只过滤大写单词的正则表达式。

请注意,此正则表达式将打印 TEST.txt 以及 TEXT.TXT。换句话说,它只会考虑由字母组成的名称。

于 2013-02-05T19:43:49.907 回答
0

ls列出了文件,而不是grep,因此您需要指定要将“/”附加到目录的位置。用于ls --classify将“/”附加到目录。

grep用于处理来自ls(或其他一些来源,一般来说)的结果,并且只显示与您指定的模式匹配的行。它不限于大写字符。您可以将其限制为仅大写字符和“/”,grep -E '^[A-Z/]*$或者如果您还需要数字、句点等,则可以改为过滤掉包含小写字符的行grep -v -E [a-z]

由于grep不是列出文件的程序,它不是您要执行递归的地方。 ls如果您使用 . 可以递归地列出路径ls -R。但是,您只会以这种方式获取文件路径的最后一个组成部分。

您可能要考虑使用find来处理递归。这对我有用:

find . -exec ls -d --classify {} \; | egrep -v '[a-z][^/]*/?$'

我应该注意,使用ls --classify将“/”附加到目录末尾也可能会将一些其他字符附加到它可以分类的其他类型的路径中。例如,它可以将“*”附加到可执行文件的末尾。如果这不行,但您可以单独列出目录和其他路径,这可以通过运行find两次来解决 - 一次用于目录,然后再次用于其他路径。这对我有用:

find . -type d | egrep -v '[a-z][^/]*$' | sed -e 's#$#/#'

find . -not -type d | egrep -v '[a-z][^/]*$'

于 2013-02-05T19:51:23.567 回答