2016-02-14 56 views
4

如果我输入lsgrep,我将如何返回一个文件列表,其条件是他们只有x个字母,包含扩展名?寻找特定字母数的字符串,grep附带的扩展名

因此,举例来说,如果ls给我:

abcde.jav a156e.exc test.c prog1.c qwert r.c 

,我期待为包含严格5个字母的所有文件,包括扩展名:

a156e.exc test.c prog1.c qwert 

我已经试过:

ls | grep '^[a-z]${5}' 
ls | grep "^[a-z]|[a-z]$" 

和其他类似的东西,但我似乎无法得到它。看来解决方案应该非常简单,但我无法弄清楚。任何帮助,将不胜感激。

+0

旁白:如果你碰巧这样做:不要使用'任何东西ls'输出。 'ls'是交互式查看目录元数据的工具。用代码解析'ls'输出的任何尝试都被破坏。 * Globs *更加简单和正确: 阅读[Parsing ls](http://mywiki.wooledge.org/ParsingLs) –

+0

'qwerty'有6个字母。这不应该匹配,对吧? –

+0

您可以使用'find'而不是'ls'。 – jpaugh

回答

3

你可以使用下面的表达式:

Live Example

^([^a-z]*[a-z][^a-z]*){5}$ 

说明:

  • ^ - 锚表示字符串的开始
  • ([^a-z]*[a-z][^a-z]*) - 组匹配零个或多个非字母字符
  • {5}之间的单个字母 - 匹配前一组的5倍
  • $ - 锚表示字符串的结束。

用法:

ls | grep -E '^([^a-z]*[a-z][^a-z]*){5}$' 

或者不ls

for f in *; do 
    if [[ $f =~ ^([^a-z]*[a-z][^a-z]*){5}$ ]] 
    then 
     echo $f 
    fi 
done 
+1

正是我一直在寻找。谢谢! – nsaftarli

+1

伟大的正则表达式。你可以避免'ls'而不使用(慢)循环:'printf'%s \ n'* |的grep -E '^([^ A-Z] * [A-Z] [^ A-Z] *){5} $''。或者,使用一个过程替代:'的grep -E '^([^ A-Z] * [A-Z] [^ A-Z] *){5} $'<(printf的 '%S \ N' *)'。 (这将仍与具有嵌入换行符的文件名打破;具有_GNU_'grep',这可以如下补救:'grep的-zoE '^([^ AZ] * [AZ] [^ AZ] *){5} $' <(printf'%s \ 0'*)')。 – mklement0