【问题标题】:Script to calculate and extract results using bash loops and AWK in a hierarchical directory structure在分层目录结构中使用 bash 循环和 AWK 计算和提取结果的脚本
【发布时间】:2020-09-04 04:04:29
【问题描述】:

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

$ 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

问题定义:我想,

  • 首先,在每个目录中找到名为wallShearStress*.dat的文件。在哪里,
  • 感兴趣的文件应该在结尾处具有最高编号。 (澄清一下,一个目录中存在多个wallShearStress*.dat 文件,例如对于DP3,应该只选择DP3\postProcessing\0\wallShearStress_0.05.dat 进行处理,因为它的优先级高于DP3\postProcessing\0\wallShearStress.dat,同样只有DP1\postProcessing\0\wallShearStress_0.02.datDP2\postProcessing\0\wallShearStress_0.1.dat 应该被选中)
  • 使用 awk 对所选的 wallShearStress*.dat 执行算术运算,对每个目录在 masterDir 中输出为 .txt/.csv 文件,如下所示:

问题

  • 这种方法有什么问题?
  • 有更好的方法吗? (请记住,问题在于获取正确的文件,而不是 AWK)。

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

【问题讨论】:

  • 感谢您指出错误。已更正。

标签: directory awk bash awk bash shell awk directory openfoam


【解决方案1】:

您可以只对父目录使用 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 排序使用. 作为字段分隔符。

  • 1234563 @重定向符号,需要和&lt;( )分开,否则会报错。

【讨论】:

  • 酷。谢谢。您能否添加一些解释,例如:1.为什么done &lt;&lt;(for d in DP*/;失败,2.2.sort -Vk2 -t.中的作用?另外注意,是不是可以让语法看起来像 for 循环中的 while 循环?
  • 您可以将输出通过管道传输到while read loop 是的,但它会在另一个子shell 中,这就是我的编写方式。
  • @massisenergy,我已经在 for 循环中用你的 while 循环更新了答案。
  • 我编辑了部分代码以匹配预期的输出。
猜你喜欢
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 2018-10-16
  • 2019-05-31
  • 1970-01-01
相关资源
最近更新 更多