我有一个目录,里面有许多目录,其名称为:
YYYYDDMM_HHMISS
示例:20140102_120202
我想只提取YYYYDDMM部分。
我试过了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]*
任何其他(更简单)的方式来实现结果?
答案 0 :(得分:4)
为什么这不会返回任何结果:
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
会执行我不想要的事情。
这就是为什么你必须引用搜索模式,以防止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]+'