首页 > 解决方案 > 在分层目录结构中使用 bash 循环和 AWK 计算和提取结果的脚本

问题描述

我有以下结构,其中包含某些感兴趣的文件,我必须使用对其进行计算/算术运算。

$ mkdir DP1/postProcessing/0/ DP2/postProcessing/0/ DP3/postProcessing/0/;
$ touch DP1/postProcessing/0/wallShearStress.dat DP1/postProcessing/0/wallShearStress_0.02.dat DP2/postProcessing/0/wallShearStress_0.dat DP2/postProcessing/0/wallShearStress_0.1.dat DP3/postProcessing/0/wallShearStress_0.05.dat DP3/postProcessing/0/wallShearStress_0.000012.dat
masterDir/;

$ tree masterDir/
masterDir/
├── DP1
│   └── postProcessing
│       └── 0
│           ├── wallShearStress_0.02.dat
│           └── wallShearStress.dat
├── DP2
│   └── postProcessing
│       └── 0
│           ├── wallShearStress_0.1.dat
│           └── wallShearStress_0.dat
└── DP3
    └── postProcessing
        └── 0
            ├── wallShearStress_0.000012.dat
            ├── wallShearStress_0.05.dat
            └── wallShearStress.dat

预期产出

DP     File_processed               Ouput_value #Optional header
DP1    wallShearStress_0.02.dat          <some result using AWK>  
DP2    wallShearStress_0.1.dat        <some result using AWK>  
DP3    wallShearStress_0.05.dat     <some result using AWK>

我的(非常基本的)尝试失败了,脚本只为找到的最后一个目录返回文件三次:

$ for i in $(find -type d -name "DP*"); do
>     for j in $(find . -type f -name "wallShearStress*" | tail -n 1); do
>         echo $j;
>         awk 'NR == 3 {print $0}' $j; # this just for example ...
>         # but I wanna do something more here, but no issue with that
>         # once I can get the proper files into AWK.
>     done;
> done;
./DP3/postProcessing/0/wallShearStress_0.05.dat
./DP3/postProcessing/0/wallShearStress_0.05.dat
./DP3/postProcessing/0/wallShearStress_0.05.dat

问题定义:我想,

问题

我更喜欢 + (因为它比有人想出其他编程语言更容易理解)。非常感谢您的参与!

标签: bashshellawkdirectoryopenfoam

解决方案


您可以对父目录使用 for 循环,对子目录使用 find 。如果你sort-V标志使用它。

#!/usr/bin/env bash

for d in masterDir/DP*/; do
  find "$d" -type f -name 'wallShearStress*'| sort -Vk2 -t.| head -n1
done

要遍历输出,您可以使用 while read 循环。

#!/usr/bin/env bash

while IFS= read -r files; do
  echo Do something with "$files"
done < <(for d in masterDir/DP*/; do find "$d" -type f -name 'wallShearStress*'| sort -Vk2 -t.| head -n1; done )

根据OP的要求的另一种选择

#!/usr/bin/env bash

for d in masterDir/DP*/; do
  while IFS= read -r files; do
    echo Do something with "$files"
  done < <(find "$d" -type f -name 'wallShearStress*'| sort -Vk2 -t.| head -n1)
done
  • -t, --field-separator=SEP use SEP instead of non-blank to blank transition.使用as 字段分隔符进行排序。

  • <()Is Process Substitution,它是某种文件,确切地说是命名管道,请参见输出ls -l <(:),并且为了从文件中读取,您需要<重定向符号,并且需要将其分开,<( )否则您将收到错误.


推荐阅读