使用bash从文本文件中的4个标记中提取文本

时间:2012-08-11 01:17:40

标签: bash sed awk

好的,这是一个棘手的问题...我有一个文件1,我想用file1中的特定文本创建一个文件2.

     random useless text 
     #START
     random IMPORTANT text
     #END 
     random useless text

     random useless text 
     #START
     random IMPORTANT text
     #END 
     random useless text

我想在第一对#START和#END(包括#' s)之间提取文本,但忽略第二对#START和#END。请注意,#START #END对在同一文件中出现两次。我只想要FIRST对之间的内容(包括#' s)。

在完成所有说完之后,我应该只有这个字面结果(仅来自#START #END的第一对:

     #START
     random IMPORTANT text
     #END

在另一篇文章中使用过:

sed -n" /这是令牌1 /,/这是令牌2 / p"

这是一种删除单个成对字符串的方法"这是令牌1"和"这是一个令牌2"

但是当我使用" #START"和" #END"在这个sed中它保留了两对#START和#END。

注意:第一个#START #END之间的内容总是与第二对#START #END之间的内容不同。

2 个答案:

答案 0 :(得分:5)

我会用awk:

awk '/#START/{flag=1} flag{print} /#END/{exit}' your_file

说明:

  1. 当前记录与包含起始标记的正则表达式匹配时设置标志。
  2. 设置标志时,打印当前记录
  3. 当记录与结束标记匹配时,程序就存在,因此不处理第二个副本
  4. 注意:可以将多个awk规则应用于记录。 另请注意:根据您的任务,您可能需要调整记录分隔符RS并输出记录分隔符ORS,例如:

    gawk -v RS='[[:space:]]+' -v ORS=' ' '/#START/{flag=1} flag{print} /#END/{exit}'

    这将记录分隔符设置为任意数量的空白字符,并将记录分隔符输出到空格。因此,令牌由空格分隔,并且没有可能的信息不会进入输出。比较,例如第一版与此版本的输入:

    blahblahblah #START
    important text
    #END blah blah blah
    fdsfs
    

    如果需要,请参阅gawk的官方参考手册:link

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed '/#START/,/#END/!d;/#END/q' file

说明:

  • /#START/,/#END/!d删除(不打印)不在#START#END之间的任何内容。这只会在#START#END
  • 之间打印
  • /#END/q退出,但在遇到#END
  • 时仍会打印