使用Shell查找没有指定文件模式的文件夹

3
目录树的结构如下所示:
.
├── A_123
│   └── 123.txt
├── A_456
│   ├── tmp
│   └── tmp.log
└── A_789
    └── 789.txt

有3个目录(A_123、A_456、A_789)。 目录名称的模式是:A_{数字},我感兴趣的文件是{数字}.txt

我想知道是否有一种方法可以获取没有{数字}.txt文件的目录A_{数字}。例如上面的例子,此脚本应该返回:

./A_456
A_456的文件夹中没有456.txt,但是A_123A_789的相关文件夹中都有它们的{numbers}.txt文件。有人有想法吗?谢谢!
4个回答

4
这里有一种方法:
for dir in *;do 
  if [ $(find "$dir" -maxdepth 1 -regex '.*/[0-9][0-9]*\.txt' | wc -l) = 0 ]; then 
    echo $dir
  fi
done

1
这里有几个问题。*也会匹配文件。正则表达式将匹配名为“.txt”的文件。使用ERE regextype,您可以说[0-9]+。虽然我的答案中存在一些类似的匹配问题,但是find的-regex选项不是POSIX标准,但由于该问题被标记为Linux,因此应该没问题。 - jordanm
1
如果由于某种原因,A_123 目录包含 000.txt(但不包含 123.txt),则该目录将不会被回显。尽管从 OP 的示例中看来,文本文件的名称始终与文件夹的编号匹配(如果存在),因此这可能不是一个问题。 - doubleDown

1

由于A_[0-9]目录不是嵌套的,您可以在循环中使用glob轻松完成此操作。此实现纯粹使用bash,并且不会生成外部实用程序:

for d in A_[0-9]*/; do         # the trailing / causes only directories to be matched
   files=("$d"/[0-9]*.txt)     # populate an array with matching text files
   ((!${#files})) && echo "$d" # echo $d if the array is empty
done

这个实现存在一些问题。它会匹配文件名如“12ab.txt”,并需要将目录中的所有文件名加载到数组中。

这里有另一种在bash中执行更准确的文件名匹配方法:

re='^[0-9]+[.]txt$'
for d in A_[0-9]*/; do
   for f in *; do
      if [[ -f $f && $f =~ $re ]]; then
         echo "$d"
         break
      fi
   done
done

1
稍微变化一下其他答案:使用bash的扩展模式匹配
shopt -s extglob nullglob
for dir in  A_+([0-9]); do
    files=($dir/+([0-9]).txt)
    (( ${#files[@]} == 0 )) && echo $dir
done

0
for file in *; do
  if [[ "$file" =~ ^A_([0-9]+)$ && ! -f "$file/${BASH_REMATCH[1]}.txt" ]]; then
    echo $file;
  fi
done

工作原理:

  1. 使用正则表达式(注意 =~ )检查文件/文件夹名称是否为以"A_"开头的数字。
  2. 同时,捕获数字(注意括号)并将其存储在 ${BASH_REMATCH[1]} 中。
  3. 接下来,检查文件夹是否包含 {number}.txt
  4. 如果没有,则输出文件夹的名称。

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