2

我对 AWK 完全陌生,但我认为这是解决我的问题的最佳方式,也是学习 AWK 的好时机。我正在尝试读取由模拟程序创建的大型数据文件。输出是人类可读的,所以它的格式不是很一致。输出示例在此图像中 http://i.imgur.com/0kf8l.png

我需要一种方法来找到像“He 2 4686A -2.088 0.0071”这样的行,通过指定“He 2 4686A”部分并获得以下两个数字。问题是“He 2 4686A -2.088 0.0071”这一行可以出现在表格中的任何位置。我知道如何找到条目“He 2 4686A”,但我不知道它在 4 列中的哪一列。所以我不知道如何处理它后面的值。一个命令让我只阅读接下来的两个单词,或者在找到匹配项后告诉我模式的位置都会有所帮助。

/He 2 4686A/ 找到线路

Ca A 3970A -0.900 0.1100 He 2 4686A -2.088 0.0071 S 3 18.67m -0.371 0.3721 Ar 4 444.7A -2.124 0.0066

任何帮助表示赞赏。

4

2 回答 2

2

第一步应该是将看似 4 列的记录转换为 1 列格式......然后它很容易,awk因为您可以过滤前 5 个字段 - 例如:

echo "He 2 4686A -2.088 0.0071" | \
awk '$1 == "He" && $2 == 2 && $3 == "4686A" {print $4, $5}'

这使

-2.088 0.0071

所以,对我来说,唯一的挑战是将您的数据转换为单列格式……从看起来很简单的图片来看,这些列似乎有一个固定的长度,您可以数数。

假设您的列宽为 30 个字符(很难从图片中分辨出来,请注意选项卡)并且您的数据位于 中input_file,那么您可以首先将数据“剪切”为 4 列,然后将输出通过管道传输到另一个awk进程

awk '{
  print substr($0,1,30)
  print substr($0,31,30)
  print substr($0,61,30)
  print substr($0,91,30)
}' input_file | \
awk '$1 == "He" && $2 == 2 && $3 == "4686A" {print $4, $5}'

如果您真的只需要锚后面的两个数字,那么我会说grepCosta 的解决方案最适合您,但是这使您有可能实现进一步的逻辑......

于 2012-08-16T19:51:58.843 回答
2

如果你不是死心塌地使用awk,grep将是最简单的方法......

egrep -o "He 2 4686A \-?[0-9.]+ \-?[0-9.]+" output.txt

编辑:上面的方法只有在间距是用空格完成时才有效,这似乎不是你的情况。为了处理制表符和/或重复空格...

egrep -o "He[ \t]+2[ \t]+4686A[ \t]+\-?[0-9.]+[ \t]+\-?[0-9.]+" output.txt

于 2012-08-16T19:55:03.723 回答