删除标记线的第一次和最后一次出现之间的线

时间:2011-12-05 08:17:20

标签: awk

使用像awk这样的Linux工具,我怎样才能获得下面示例中不在# NUMBERS行之间的所有行?换句话说,我只想要在第一个# NUMBERS之前和最后一个# NUMBERS之后的行。

注意:标记并不总是# NUMBERS,但#NUMBERS之间可能有任意数量的空格

输入

 param1=23
 param2=34
 param3=4

 #    NUMBERS

 343546
 3454
 657
 534

 #   NUMBERS

 5454

 # NUMBERS

 param4=41

预期输出

 param1=23
 param2=34
 param3=4
 param4=41

6 个答案:

答案 0 :(得分:2)

主要观点是:

  • 在“#NUMBER”之前打印行;
  • 请勿在“#NUMBER”之后打印行;
  • 在最后的打印缓冲区。

所以

$> cat ./printOutsideNumbers.awk 
/#( )*NUMBER/ {
    if (insideSection == 0) {
        insideSection = 1;
    } else {
        sectionBuffer = ""
    }
}
! insideSection {
    print $0
}
insideSection && ! /#( )*NUMBER/ {
    sectionBuffer = sectionBuffer"\n"$0
}
END {
    print sectionBuffer
}

$> awk -f ./printOutsideNumbers.awk file.data.txt
param1=23
param2=34
param3=4



param4=41

答案 1 :(得分:1)

以下是使用tacawk的方法:

(
  cat data.txt | awk '/# *NUMBERS/ { nextfile } 1';
  tac data.txt | awk '/# *NUMBERS/ { nextfile } 1' | tac
)

答案 2 :(得分:0)

肯定有比这更简单的代码。

awk '{if($0 ~ /#[ ]*NUMBERS/){i++;next;}if(i%2==0 )print}' data.txt

输出

param1=23
param2=34
param3=4


param4=41

答案 3 :(得分:0)

尝试下一个 awk 命令。它将文件与字符串'#NUMBER'分开,并打印删除空格的第一个和最后一个寄存器。

awk 'BEGIN { RS = "#[[:space:]]+NUMBERS"; }
     FNR == 1 { sub(/^[[:space:]]*/, "", $0); sub(/[[:space:]]*$/, "", $0); print }
     END { sub(/^[[:space:]]*/, "", $0); sub(/[[:space:]]*$/, "", $0); print }' infile

输出:

param1=23
 param2=34
 param3=4
param4=41

答案 4 :(得分:0)

这可能对您有用:

 sed '1{h;d};H;${x;s/[^\n]*\(NUMBERS\).*\1.*\n//;p};d' file.data.txt

说明:

将文件粘贴到sed的保留空间中。然后在文件末尾,交换到HS,删除NUMBERS之间的任何内容并打印出剩余部分。

或者这个:

sed '/NUMBERS/=;d' file.data.txt | 
sed -n '1h;${x;G;s/\n/,/;s,.*,sed &d file.data.txt,p}' | sh

说明:

注意NUMBERS的行号。使用第一个和最后一个地址构建sed脚本以删除不需要的行。将脚本传递给shell运行。

答案 5 :(得分:0)

一个有趣的“贪婪”线匹配问题。 “tac”一个很脏很好:)我的就像#3

BEGIN { buffer = ""; ignore = 0; }

/^# *NUMBERS/ {
    if (ignore == 0) {
        print buffer;
        ignore += 1;
    }

    buffer = ""; next;
} 

NF > 0 {
    buffer = sprintf("%s%s\n", buffer, $0)
}

END { print buffer; }

我认为FS =“\ n”; RS =“”,然后使用贪婪的正则表达式也会做的伎俩,但这将是诱人的,而不是愚蠢......