首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在图案之间打印-awk

在图案之间打印-awk
EN

Stack Overflow用户
提问于 2015-10-07 23:07:58
回答 5查看 185关注 0票数 0

我有以下输入文件

代码语言:javascript
复制
-------------------------------------
--- A-TKE spectrum (post-neutron)---
-------------------------------------

2-dim. array: (A =  73 To  162 Step 1) (E =  122 To  198 Step 1)

(The data are written according to the loop structure specified above.
The last loop is the inner-most one. Line breaks are not related to the data structure!

 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 0 2 0 0 1 0 0 0 0 


    </A_TKE>
  </Results>

这个文件是一个更大的文件的一部分,它包含更多类似于上面的数字块。

我想做的是在一个单独的文件中打印文件中的数字。作为第一次尝试,我想“让我们打印两种模式之间的内容”。开始模式将为--- A-TKE spectrum (post-neutron)---,结束模式将为</A_TKE>

我用过

代码语言:javascript
复制
awk '/--- A-TKE spectrum (post-neutron)---/{flag=1;next}/</A_TKE>/{flag=0}flag{print}' input

令我惊讶的是,屏幕上什么也没有打印出来。你知道为什么会发生这种情况吗?

我现在还想看看是否可以用一个数字替换next,这个数字将对应于我想要在给定模式之后打印的行。

EN

回答 5

Stack Overflow用户

发布于 2015-10-07 23:13:59

在perl中(因为当您开始使用awk时,它也被标记为perl ):

代码语言:javascript
复制
perl -ne 'print if m/post-neutron/...m/A_TKE/' input

它会做你的东西想要做的事。

它的工作方式是使用range operator --这是一个perl结构,用于测试当前文件是否在两个标记之间。

事实上,perl可以像awksed一样内联运行。-ne说“将这段代码包装在一个while循环中”,每次迭代一行。(例如,默认情况下sed/awk/grep是这样做的)。

否则..。这在一定程度上取决于文件中的其他内容。因为从你给出的样本中-唯一以数字开头的行是你想要的。所以:

代码语言:javascript
复制
perl -ne 'print if m/^\s*\d+\s*\d+/'

(或者结合这两个测试:

代码语言:javascript
复制
perl -ne 'print if m/post-neutron/...m/A_TKE/ and m/^\s*\d+\s*\d+/'

它将输出行首为number-space-number的两个文本标记之间的任何内容。

票数 3
EN

Stack Overflow用户

发布于 2015-10-07 23:21:36

您的awk脚本就快到了。我会这样构建它:

代码语言:javascript
复制
awk '
  /<\/A_TKE>/ {exit}
  flag && NF==50 {print} 
  /--- A-TKE spectrum .post-neutron.---/ {flag=1}
' input

当然,你可以对它进行优化,但只要看看它的逻辑,你的想法是,一旦你达到了结束标记,你就不需要进一步的处理。并且您只想在开始标记之后开始打印。

请注意,我已经将开始标记中的括号替换为点,因为括号被解释为正则表达式的一部分。我相信您可能正在考虑搜索这些简单的字符串,但它们是正则表达式。

票数 3
EN

Stack Overflow用户

发布于 2015-10-07 23:51:22

一些工作点子

Awk可以使用这个简单的命令在两个匹配的行之间打印:

代码语言:javascript
复制
awk '/PATTERN1/,/PATTERN2/' file.txt

如果希望更好地控制找到行时发生的情况,可以使用标志方法。

代码语言:javascript
复制
awk '/A-TKE/{f=1;for (i=0;i<7;i++){getline}}/A_TKE/{f=0}f' file.txt 

调整i<7以指定要跳过的行数。

此外,在这种特殊情况下,您可以利用这样一个事实,即您有50个数字字段,这不太可能出现在文件中的其他任何地方。因此,您还可以使用以下命令获取感兴趣的数字:

代码语言:javascript
复制
awk 'NF>40' file.txt

NF是一个特殊的awk变量,用于存储当前记录(行)中的字段(列)数。

为什么你的方法行不通

您的方法不起作用,因为awk中//之间的所有内容都被视为正则表达式。在您的示例中,字符串中有几个-(),它们没有转义,因此具有特殊的含义,因此您键入的表达式永远不会匹配,因此标志永远不会设置为1,awk也不会打印一行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32995911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档