grep -o并使用ls显示文件名的一部分

时间:2014-01-06 15:48:45

标签: linux bash shell unix awk

我有一个目录,里面有许多目录,其名称为: YYYYDDMM_HHMISS 示例:20140102_120202 我想只提取YYYYDDMM部分。 我试过了ls -l|awk '{print $9}'|grep -o ^[0-9]*并得到了答案。 但是我有以下问题:

  1. 为什么不返回任何结果:ls -l|awk '{print $9}'|grep -o [0-9]*。事实上它应该返回所有目录。 奇怪的是,在[0-9]之前包含'^'可以正常工作: ls -l|awk '{print $9}'|grep -o ^[0-9]*

  2. 任何其他(更简单)的方式来实现结果?

3 个答案:

答案 0 :(得分:4)

  

为什么这不会返回任何结果:ls -l|awk '{print $9}'|grep -o [0-9]*

如果当前目录中的文件以[0-9]开头,那么shell会在调用grep之前展开它们。例如,如果我有两个文件a1a2a3并运行此文件:

ls | grep a*

扩展文件名后,shell将运行此命令:

ls | grep a1 a2 a3

其结果是,它会在a2a3中打印与文本“a1”匹配的行。它也会忽略来自stdin的任何内容,因为当你为grep(第二个参数及更高版本)指定文件名时,它将忽略stdin。

接下来,请考虑一下:

ls | grep ^a*

这里,^对shell没有特殊意义,所以它逐字使用它。由于我没有以^a开头的文件名,因此会使用^a*作为模式。如果我确实有^asomething^another等文件名,那么^a*会扩展为这些文件名,而grep会执行我不想要的事情。

这就是为什么你必须引用搜索模式,以防止shell扩展它们。 find /path -name 'pattern'中的模式也是如此。

至于你想要的更简单的方法,我认为应该这样做:

ls | sed -ne 's/_.*//p'

答案 1 :(得分:3)

仅显示目录名称的YYDDMM部分:

for i in ./*; do echo $(basename "${i%%_*}"); done

一旦你得到它,不知道你想用它做什么......

答案 2 :(得分:2)

您必须避免解析ls输出。

简单就是使用这个printf:

printf "%s\n" [0-9]*_[0-9]*|egrep -o '^[0-9]+'