使用bash在文本文件中提取2个标记之间的行

时间:2011-01-31 23:42:47

标签: bash

我有一个文本文件,如下所示:

random useless text 
<!-- this is token 1 --> 
para1 
para2 
para3 
<!-- this is token 2 --> 
random useless text again

我想在令牌之间提取文本(当然不包括令牌)。我尝试使用##和%%来提取数据,但它不起作用。我认为它不适用于操纵如此大的文本文件。有什么建议我怎么做?也许awk或sed?

7 个答案:

答案 0 :(得分:39)

无需headtailgrep或多次阅读该文件:

sed -n '/<!-- this is token 1 -->/{:a;n;/<!-- this is token 2 -->/b;p;ba}' inputfile

说明:

  • -n - 不要进行隐式打印
  • /<!-- this is token 1 -->/{ - 如果找到了起始标记,那么
    • :a - 标签“a”
      • n - 阅读下一行
      • /<!-- this is token 2 -->/q - 如果它是结束标记,则退出
      • p - 否则,请打印
    • ba - 分支以标记“a”
  • } if if

答案 1 :(得分:25)

你可以提取它,包括带有sed的标记。然后用头部和尾部剥去令牌。

... | sed -n "/this is token 1/,/this is token 2/p" | head -n-1 | tail -n+2

答案 2 :(得分:1)

尝试以下方法:

sed -n '/<!-- this is token 1 -->/,/<!-- this is token 2 -->/p' your_input_file
        | egrep -v '<!-- this is token . -->'

答案 3 :(得分:1)

也许sed和awk有更优雅的解决方案,但我有一个“穷人的”方法,有grep,cut,head和tail。

#!/bin/bash

dataFile="/path/to/some/data.txt"
startToken="token 1"
stopToken="token 2"

startTokenLine=$( grep -n "${startToken}" "${dataFile}" | cut -f 1 -d':' )
stopTokenLine=$( grep -n "${stopToken}" "${dataFile}" | cut -f 1 -d':' )

let stopTokenLine=stopTokenLine-1
let tailLines=stopTokenLine-startTokenLine

head -n ${stopTokenLine} ${dataFile} | tail -n ${tailLines}

答案 4 :(得分:1)

无需调用强大的sed / awk / perl。你可以“仅限bash”:

#!/bin/bash
STARTFLAG="false"
while read LINE; do
    if [ "$STARTFLAG" == "true" ]; then
            if [ "$LINE" == '<!-- this is token 2 -->' ];then
                    exit
            else
                    echo "$LINE"
            fi
    elif [ "$LINE" == '<!-- this is token 1 -->' ]; then
            STARTFLAG="true"
            continue
    fi
done < t.txt

亲切的问候

realex

答案 5 :(得分:0)

对于这样的事情,我会通过sedawk功能的组合({等级}}来达到Perl。像(小心 - 未经测试)的东西:

my $recording = 0;
my @results = ();
while (<STDIN>) {
   chomp;
   if (/token 1/) {
      $recording = 1;
   }
   else if (/token 2/) {
      $recording = 0;
   }
   else if ($recording) {
      push @results, $_;
   }
}

答案 6 :(得分:0)

sed -n "/TOKEN1/,/TOKEN2/p" <YOUR INPUT FILE> | sed -e '/TOKEN1/d' -e '/TOKEN2/d'