[英]bash looping and extracting of the fragment of txt file
我正在处理位于工作目录中的大量 dlg 文本文件的分析。 每个文件都有一个表格(通常位于日志的不同位置),格式如下:
文件 1:
CLUSTERING HISTOGRAM
____________________
________________________________________________________________________________
| | | | |
Clus | Lowest | Run | Mean | Num | Histogram
-ter | Binding | | Binding | in |
Rank | Energy | | Energy | Clus| 5 10 15 20 25 30 35
_____|___________|_____|___________|_____|____:____|____:____|____:____|____:___
1 | -5.78 | 11 | -5.78 | 1 |#
2 | -5.53 | 13 | -5.53 | 1 |#
3 | -5.47 | 17 | -5.44 | 2 |##
4 | -5.43 | 20 | -5.43 | 1 |#
5 | -5.26 | 19 | -5.26 | 1 |#
6 | -5.24 | 3 | -5.24 | 1 |#
7 | -5.19 | 4 | -5.19 | 1 |#
8 | -5.14 | 16 | -5.14 | 1 |#
9 | -5.11 | 9 | -5.11 | 1 |#
10 | -5.07 | 1 | -5.07 | 1 |#
11 | -5.05 | 14 | -5.05 | 1 |#
12 | -4.99 | 12 | -4.99 | 1 |#
13 | -4.95 | 8 | -4.95 | 1 |#
14 | -4.93 | 2 | -4.93 | 1 |#
15 | -4.90 | 10 | -4.90 | 1 |#
16 | -4.83 | 15 | -4.83 | 1 |#
17 | -4.82 | 6 | -4.82 | 1 |#
18 | -4.43 | 5 | -4.43 | 1 |#
19 | -4.26 | 7 | -4.26 | 1 |#
_____|___________|_____|___________|_____|______________________________________
目的是遍历所有 dlg 文件并从表中取出与更宽集群相对应的单行(直方图列中的斜线数量更大)。 在上表的示例中,这是第三行。
3 | -5.47 | 17 | -5.44 | 2 |##
然后我需要将此行与日志文件的名称(应在该行之前指定)一起添加到 final_log.txt 中。 所以最后我应该有以下格式的东西(对于 3 个不同的日志文件):
"Name of the file 1": 3 | -5.47 | 17 | -5.44 | 2 |##
"Name_of_the_file_2": 1 | -5.99 | 13 | -5.98 | 16 |################
"Name_of_the_file_3": 2 | -4.78 | 19 | -4.44 | 3 |###
我的 BASH 工作流程的一个可能模型是:
#!/bin/bash
do
file_name2=$(basename "$f")
file_name="${file_name2/.dlg}"
echo "Processing of $f..."
# take a name of the file and save it in the log
echo "$file_name" >> $PWD/final_results.log
# search of the beginning of the table inside of each file and save it after its name
cat $f |grep 'CLUSTERING HISTOGRAM' >> $PWD/final_results.log
# check whether it works
gedit $PWD/final_results.log
done
在这里,我需要替换 echo 和 grep 的组合以获取表格的选定部分。
您可以使用这个,预计速度足够快。 除了表格之外,文件中的额外行预计不会成为问题。
grep "#$" *.dlg | sort -rk11 | awk '!seen[$1]++'
grep
获取所有直方图行,然后按最后一个字段以相反的顺序排序,这意味着最多#
行在顶部,最后awk
删除重复项。 请注意,当grep
解析多个文件时,默认情况下-H
在行的开头打印文件名,因此如果您对一个文件进行测试,请使用grep -H
。
结果应该是这样的:
file1.dlg: 3 | -5.47 | 17 | -5.44 | 2 |##########
file2.dlg: 3 | -5.47 | 17 | -5.44 | 2 |####
file3.dlg: 3 | -5.47 | 17 | -5.44 | 2 |#######
这是在文件中有许多相等的最大行的情况下获得第一次出现的修改:
grep "#$" *.dlg | sort -k11 | tac | awk '!seen[$1]++'
我们用反转文件流的“tac”命令替换了 sort 中的 reversed 参数,所以现在对于任何相等的行,初始顺序被保留。
第二种解决方案
这里只使用 awk:
awk -F"|" '/#$/ && $NF > max[FILENAME] {max[FILENAME]=$NF; row[FILENAME]=$0}
END {for (i in row) print i ":" row[i]}' *.dlg
更新:如果您从不同的目录执行它并且只想保留每个文件的基本名称,请删除路径前缀:
awk -F"|" '/#$/ && $NF > max[FILENAME] {max[FILENAME]=$NF; row[FILENAME]=$0}
END {for (i in row) {sub(".*/","",i); print i ":" row[i]}}'
作为 awk 脚本可能更有意义。
在输入文件中出现平局的情况下,这将选择具有最宽直方图的第一行。
#!/bin/bash
awk 'FNR == 1 { if(sel) print sel; sel = ""; max = 0 }
FNR < 9 { next }
length($10) > max { max = length($10); sel = FILENAME ":" $0 }
END { if (sel) print sel }' ./"$prot"/*.dlg
这假设直方图始终是第十个字段; 如果您的输入格式比您显示的肿块更混乱,则可能会适应口味。
更详细地说,第一行在每个输入文件的第一行触发。 如果我们收集了前一行(意味着这不是第一个输入文件),打印它,然后重新开始。 否则,初始化第一个输入文件。 将sel
设置为sel
将max
设置为零。
第二行跳过包含标题的第 1-8 行。
第三行检查当前行的直方图是否长于max
。 如果是,将max
更新为该直方图的长度,并记住sel
的当前行。
最后一行是我们处理完所有文件时的溢出。 我们从来没有从最后一个文件中打印sel
,所以也打印它,如果它被设置了。
如果你的意思是说我们应该找到CLUSTERING HISTOGRAM
和表格末尾之间的线,我们可能应该有更多关于周围线是什么样子的信息。 不过,也许是这样的;
awk '/CLUSTERING HISTOGRAM/ { if (sel) print sel; looking = 1; sel = ""; max = 0 }
!looking { next }
looking > 1 && $1 != looking { looking = 0; nextfile }
$1 == looking && length($10) > max { max = length($10); sel = FILENAME ":" $0 }
END { if (sel) print sel }' ./"$prot"/*.dlg
这台looking
到1的时候,我们看到CLUSTERING HISTOGRAM
,然后计数到第一线looking
不再增加。
我建议使用awk处理:
for i in $FILES
do
echo -n \""$i\": "
awk 'BEGIN {
output="";
outputlength=0
}
/(^ *[0-9]+)/ { # process only lines that start with a number
if (length(substr($10, 2)) > outputlength) { # if line has more hashes, store it
output=$0;
outputlength=length(substr($10, 2))
}
}
END {
print output # output the resulting line
}' "$i"
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.