如何在Unix shell脚本中循环遍历与正则表达式匹配的文件

13
我希望能够循环遍历符合特定模式的文件列表。我可以使用带有正则表达式的ls和egrep列出这些文件,但我找不到将其转换为迭代过程的方法。我怀疑使用ls不是答案。非常感谢您的任何帮助。

我的当前ls命令如下:

ls | egrep -i 'MYFILE[0-9][0-9]([0][1-9]|1[0-2])([0][1-9]|[12][0-9]|[3][01]).dat'
我希望以上内容可以匹配以下文件名:
  • MYFILE160418.dat
  • myFILE170312.DAT
  • MyFiLe160416.DaT
但不包括以下文件名:
  • MYOTHERFILE150202.DAT
  • Myfile.dat
  • myfile.csv
谢谢, Paul.

嗨@paul-frith,你应该从whilefor开始。像这个例子中使用一个计数器-> http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html - Andy K
在许多情况下,您不需要显式循环,因为您可以通过管道将参数传递给另一个程序,可能使用 xargs - Michael Vehrs
太棒了,谢谢 - 我没意识到你可以在for循环中使用ls命令。 - paul frith
尝试:ls | egrep -i 'MYFILE\d{6}\.dat' - Saleem
Saleem,虽然更整洁,但我认为这将给予更宽松的匹配标准,使用你的方法将允许月份大于12和日期大于31。 - paul frith
2个回答

8
您可以使用(GNU)find命令的正则表达式搜索选项,而不是解析ls命令。
find . -regextype "egrep" \
       -iregex '.*/MYFILE[0-9][0-9]([0][1-9]|1[0-2])([0][1-9]|[12][0-9]|[3][01]).dat' \
       -exec [[whatever you want to do]] {} \;

在文件名上执行命令的指令是 [[whatever you want to do]]

来自手册页面。

-regextype type
          Changes  the regular expression syntax understood by -regex and -iregex tests 
          which occur later on the command line.  Currently-implemented types are 
          emacs (this is the default),posix-awk, posix-basic, posix-egrep and 
          posix-extended.

  -regex pattern
          File name matches regular expression pattern.  This is a match on the whole 
          path, not a search.  For example, to match a file named `./fubar3', you can 
          use the regular expression
          `.*bar.' or `.*b.*3', but not `f.*r3'.  The regular expressions understood by 
          find are by default Emacs Regular Expressions, but this can be changed with 
          the -regextype option.

  -iregex pattern
          Like -regex, but the match is case insensitive.

1
有趣的是,我一开始就想用“find”,但我不能让我的正则表达式起作用。-regextype“egrep”才是我需要的! - paul frith

8

根据Andy K提供的链接,我使用以下内容根据我的匹配条件进行循环:

for i in $(ls | egrep -i 'MYFILE[0-9][0-9]([0][1-9]|1[0-2])([0][1-9]|[12][0-9]|[3][01]).dat' ); do             
 echo item: $i;         
done

我已经查看了这个问题,似乎解析ls是一个坏主意,因为UNIX允许文件名中包含几乎任何字符,包括换行符等。但是,考虑到我正在使用正则表达式匹配,那么在这种情况下,这个问题肯定会得到缓解。还有其他原因不解析ls吗? - paul frith
1
不要使用ls输出进行任何操作。 ls只是一个交互式查看目录元数据的工具。尝试使用代码解析ls输出都是错误的。使用通配符会更简单且正确: for file in *.txt。请阅读 Parsing ls - Rany Albeg Wein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接