bash - 在分层目录结构中使用 bash 循环和 AWK 计算和提取结果的脚本
问题描述
我有以下目录结构,其中包含某些感兴趣的文件,我必须使用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
问题定义:我想,
- 首先,在每个目录中找到名为
wallShearStress*.dat
. 在哪里, - 感兴趣的文件应该在结尾处具有最高编号。(澄清一下,一个目录中存在多个
wallShearStress*.dat
文件,例如 forDP3
onlyDP3\postProcessing\0\wallShearStress_0.05.dat
应该被选择进行处理,因为它的优先级高于DP3\postProcessing\0\wallShearStress.dat
,类似 onlyDP1\postProcessing\0\wallShearStress_0.02.dat
并且DP2\postProcessing\0\wallShearStress_0.1.dat
应该被选择) - 使用 awk 对
wallShearStress*.dat
每个目录执行算术运算,并在/文件中输出如下masterDir
:.txt
.csv
问题
- 方法有什么问题?
- 有更好的方法吗?(请记住,问题在于获取正确的文件,而不是 AWK)。
解决方案
您可以对父目录使用 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 <(:)
,并且为了从文件中读取,您需要<
重定向符号,并且需要将其分开,<( )
否则您将收到错误.
推荐阅读
- c - 从 c 中的命令输出中提取值
- java - IBM Websphere MQ Latency 用于存储持久消息 Java 客户端
- reactjs - 当我尝试从减速器访问状态信息时,它显示未定义
- java - 如何在 Android 10(Android Q) 或更高版本上连接到半径认证的 Wifi 设备
- c# - 在 if 语句中检查以“ugle”开头的字符串后,如何将其保存在新数组中?
- django - drf-yasg:如何更改 operationId?
- java - 如何将外部工作簿数据设置为图表的数据源?
- python - 关于python中的类和函数的问题
- python-3.x - Django3 在运行时刷新/重新加载配置设置
- svn - 在 SVN 合并中添加和删除文件