【问题标题】:How to find integer values and compare them then transfer the main files?如何找到整数值并比较它们然后传输主文件?
【发布时间】:2016-12-13 14:19:33
【问题描述】:

我有一些 .log 的输出文件(5000 个文件),它们是 QM 计算的结果。在每个文件中,有两条特殊的行表示电子和轨道的数量,如下所示(与输出文件中的精确空格相同):

    Number of electrons               =        9
    Number of orbitals                =       13

我想到了一个脚本(bash 或 Fortran),作为这个问题的解决方案,它 grep 这两行(同时)并获取相应的整数值(例如 9 和 13),比较它们并找到两个值之间的差异,最后,将它们列出在具有相应文件名的新文本文件中。 我非常感谢您提供的任何帮助。

【问题讨论】:

  • 整个文件中只有这两行的一个实例?
  • @Amir 到目前为止您尝试过什么?这是一个比较简单的awk 问题。请查看一些文档或在线教程,而不是不尝试就问。
  • 要开始,请尝试awk -F= '/^Number/ {print $2}' file,它将为您提供要减去的值。然后你可以将它们保存在变量中并做减法或在awk 本身中做差异。然后是重定向到输出文件的问题。
  • @Inian 是的,每个文件只有这两个特殊行,没有类似的行存在
  • @VarunM 我实际上用“and”和“or”条件命令尝试了一些 grep -w 和 grep -Eo 。但首先,它们都没有给我确切对应的整数值,其次,该命令不能单独工作,这就是为什么我正在考虑编写一个包含所有命令的脚本。抱歉,我完全是脚本和命令的初学者。

标签: bash scripting grep fortran string-comparison


【解决方案1】:

我在GNU Awk 中发布了一个尝试,并且仅在其中进行了测试。

#!/bin/bash

for file in *.log
do
    awk -F'=[[:blank:]]*' '/Number of/{printf "%s%s",$2,(NR%2?" ":RS)}' "$file" | awk 'function abs(v) {return v < 0 ? -v : v} {print abs($1-$2)}' >> output_"$file"
done

我将AWK 逻辑拆分为两个的原因是为了降低在单个巨大命令中执行此操作的复杂性。第一部分用于从日志文件中以列格式提取数字,第二部分用于获取它们的绝对值。

我会分解AWK的逻辑:-

  • -F'=[[:blank:]]*' 是一个多字符分隔符逻辑,包括 = 和一个或多个 [[:blank:]] 空白字符实例。
  • '/Number of/{printf "%s%s",$2,(NR%2?" ":RS)}' 搜索以 Number of 开头的行并以列方式打印,即示例文件中的 9 13

  • 第二部分是不言自明的。我写了一个函数,从两个返回值中获取绝对值并打印出来。

  • 每个输出都保存在一个名为 output_ 的文件中,供您进一步处理。

从命令行以bash script.sh 运行脚本,其中script.sh 是包含上述行的名称。

更新:-

如果您也对负值感兴趣,即没有绝对函数,请将 awk 语句更改为

awk -F'=[[:blank:]]*' '/Number of/{printf "%s%s",$2,(NR%2?" ":RS)}' "$file" | awk '{print ($1-$2)}' >> output_"$file"

【讨论】:

  • 非常感谢 Inian 的热心帮助!代码完美运行。但是还有一个问题;如果我不希望得到两个值相减的绝对值(负值也很重要),那么应该对代码进行哪些更改?
  • Yeeeeaaaaaaahh 它有效。真的谢谢你,非常感谢你的帮助,非常感谢!
  • @Amir:乐于助人!
【解决方案2】:

这样做的方法不好(但它会起作用)-

while read file
do
    first=$(awk -F= '/^Number/ {print $2}' "$file" | head -1) 
    second=$(awk -F= '/^Number/ {print $2}' "$file" | tail -1) 

    if [ "$first" -gt "$second" ] 
    then 
        echo $(("$first" - "$second")) 
    else 
        echo $(("$second"  - "$first"))
    fi > "$file"_answer ; 
done < list_of_files

此方法获取值(在awk 一个衬里并比较它们。

然后将它们相减,得到一个值,并将其保存在名为“$file”_answer 的文件中。即带有“_answer”作为名称后缀的初始文件名。

您可能需要调整此代码以完全符合您的目的。

【讨论】:

  • 非常感谢 Varun M 的热心帮助和回答!不幸的是,该代码对我不起作用,但我非常感谢您的帮助。我什至试图改变它以消除 IF 语句并保持这条线; echo $(("$first" - "$second")),但它不再起作用。但是再次感谢你!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多