3

目录树是这样的:

.
├── A_123
│   └── 123.txt
├── A_456
│   ├── tmp
│   └── tmp.log
└── A_789
    └── 789.txt

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

我想知道是否有办法获取其中A_{numbers}没有{numbers}.txt文件的目录。例如上面,这个脚本应该返回:

./A_456

as在其文件夹A_456中没有,但在相关文件夹中有其文件。456.txtA_123A_789{numbers}.txt

有人对此有想法吗?谢谢!

4

4 回答 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
于 2012-10-30T05:21:42.550 回答
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
于 2012-10-30T06:09:01.517 回答
1

其他几个答案略有不同:使用 bash扩展模式匹配

shopt -s extglob nullglob
for dir in  A_+([0-9]); do
    files=($dir/+([0-9]).txt)
    (( ${#files[@]} == 0 )) && echo $dir
done
于 2012-10-30T15:18:52.973 回答
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. 如果没有,请回显文件夹的名称。
于 2012-10-30T13:53:38.457 回答