2014-01-06 44 views
1

的文件名显示部我有作为在其内部具有许多目录及其名称的图案的目录: YYYYDDMM_HHMISS 实施例:20140102_120202 欲仅提取YYYYDDMM一部分。 我试过ls -l|awk '{print $9}'|grep -o ^[0-9]*并得到了答案。 但是我有以下问题:的grep -o和使用LS

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

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

+1

原因'[0-9] *'什么也没有匹配是什么都没有足够的匹配,所以'grep'停在那里。尝试'[0-9] [0-9] *'或'grep -E'[0-9] +'',尽管没有锚也会匹配时间戳。 – tripleee

+0

务必引用正则表达式来防止shell试图将其视为模式。如果shell成功,则正则表达式将被替换为匹配它的文件名列表。 – chepner

回答

2

您必须避免解析ls输出。

简单的就是用这个的printf:

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

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

如果在当前目录中的文件与[0-9]开始,然后壳将在致电grep之前展开它们。举例来说,如果我有两个文件a1a2a3并运行此:

ls | grep a* 

的文件名扩展后,外壳就会运行此:

ls | grep a1 a2 a3 

其结果是,它将打印在a2a3线匹配文本“A1”这一点。它还将忽略无论是从标准输入设备来了,因为当你指定的文件名grep(第二个参数及以后),它会忽略标准输入。

其次,考虑一下:

ls | grep ^a* 

这里,^没有特殊意义的外壳,所以使用它一字不差。由于我没有以^a开头的文件名,它将使用^a*作为模式。如果我也有像^asomething^another,然后再次文件名,^a*将扩大到这些文件名和grep会做一些我并没有真正打算。

这就是为什么你要引用的搜索模式,以防止shell扩展它们。这同样适用于find /path -name 'pattern'中的模式。

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

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

,只显示目录名的YYDDMM部分:

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

不知道你想要用它做一次,但你得到它虽然...

+0

或'因为我在*;做回声“$ {i %% _ *}”;或许。 –

+0

是的,确实更清洁。 – Platoxia