我有一个目录,里面有很多目录,它们的名称模式如下:YYYYDDMM_HHMISS示例:20140102_12022我只想提取YYYDDMM部分。我尝试了ls -l|awk '{print $9}'|grep -o ^[0-9]*
并得到了答案。然而,我有以下问题:
-
为什么不返回任何结果:
ls -l|awk '{print $9}'|grep -o [0-9]*
。事实上,它应该返回所有目录。奇怪的是,在[0-9]之前只包含"^"很好:ls -l|awk '{print $9}'|grep -o ^[0-9]*
-
还有其他(更简单的)方法可以达到这个结果吗?
为什么不返回任何结果:
ls -l|awk '{print $9}'|grep -o [0-9]*
如果当前目录中有以[0-9]
开头的文件,则shell将在调用grep
之前展开这些文件。例如,如果我有两个文件a1
、a2
和a3
,并运行以下命令:
ls | grep a*
文件名展开后,shell将运行以下命令:
ls | grep a1 a2 a3
其结果是,它将打印a2
和a3
中与文本"a1"匹配的行。它还将忽略来自stdin的任何内容,因为当您为grep
(第二个参数及以上)指定文件名时,它将忽略stdin。
接下来,考虑一下:
ls | grep ^a*
这里,^
对shell没有特殊意义,所以它逐字逐句地使用它。由于我没有以^a
开头的文件名,所以它将使用^a*
作为模式。如果我确实有像^asomething
或^another
这样的文件名,那么^a*
将被扩展到这些文件名,而grep
将做一些我并不打算做的事情。
这就是为什么你必须引用搜索模式,以防止外壳扩展它们。find /path -name 'pattern'
中的模式也是如此。
至于你想要的更简单的方法,我认为应该这样做:
ls | sed -ne 's/_.*//p'
只显示目录名的YYYDMM部分:
for i in ./*; do echo $(basename "${i%%_*}"); done
不过,不确定一旦你有了它,你想用它做什么。。。
必须避免解析ls
输出。
简单就是使用这个打印f:
printf "%sn" [0-9]*_[0-9]*|egrep -o '^[0-9]+'