【问题标题】:Regex with positive and negative selection in for loop to iterate through a list of files正则表达式在 for 循环中进行正负选择以遍历文件列表
【发布时间】:2019-06-16 20:48:28
【问题描述】:

我很难遍历多个文件,这些文件根据多个标准(由正则表达式定义)选择一个。例如,从下面列出的文件中,我只想选择具有 txt 扩展名的文件,但包含字符串“cat”的文件除外:

mousecatdog.txt
dogcowfox.gif
dogmousecat.txt
dogmousepig.txt

所以我只想从此列表中获取dogmousepig.txt。

我尝试使用负前瞻,但出现错误:

syntax error near unexpected token `('

当然看了论坛上的其他帖子,也尝试过加括号()或者启用shopt -s extglob来解决问题,但无济于事。

我使用的是 mac,脚本是 bash。

 #!/bin/bash
    for FILE in ^((?!cat).)*.txt
     do
      printf "\$FILE\n" 
     done 

【问题讨论】:

  • 尝试添加if:for FILE in *.txt; do if [[ "$FILE" != *cat* ]]; then echo "$FILE" fi; done

标签: bash shell glob


【解决方案1】:

in 之后不能使用正则表达式,但可以使用 glob 模式。通过shopt -s extglob,您可以使用扩展模式:

#! /bin/bash
shopt -s extglob
for f in !(*cat*).txt ; do
    printf "$f\n"
done

为防止模式在没有匹配文件时扩展到自身,您还需要启用nullglob。

【讨论】:

  • 谢谢!但是有了这个我也得到了错误:意外标记附近的语法错误`('
  • @LechKaczmarczyk:你启用extglob了吗?
【解决方案2】:

Bash 在您的示例中使用通配符扩展,而不是正则表达式。

我看到了两个相当简单的解决方案:

1- 对正选择使用通配符,对负选择使用 RE,就像 @Wiktor Stribizew 在他的评论中所说:

for FILE in *.txt; do
   if [[ ! $FILE =~ cat ]]; then
      printf "$FILE\n" 
   fi
done

2- grep 出通配符扩展的输出(尽管如果文件名中有空格,这将无法正常工作):

for FILE in `\ls -1 *.txt | grep -v cat`; do
   printf "$FILE\n"
done

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2014-11-25
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多