从文件中提取连续匹配行的第一个块?

从文件中提取连续匹配行的第一个块?

所以我有一个这样的文件:

echo 'this line is added for demo purpose'
echo 'do not extract this line and the line above'

#!/usr/bin/env bash
# header: add, replace, and delete header lines.
# 
# Example usage:
# $ seq 10 | header -a 'values'
# $ seq 10 | header -a 'VALUES' | header -e 'tr "[:upper:]" "[:lower:]"'
# $ seq 10 | header -a 'values' | header -d
# $ seq 10 | header -a 'multi\nline' | header -n 2 -e "paste -sd_"
#
# See also: body
#

# Author: http://jeroenjanssens.com

usage () {
cat << EOF
header: add, replace, and delete header lines.

usage: header OPTIONS

OPTIONS:
...
}

# i don't want
# these comments

# even if 
# these lines match

我想^(#.*)|(\s*)$从匹配的文件的第一行中提取与 regex 匹配的所有行,连续地到匹配的最后一行。

期望的提取结果应该是


#!/usr/bin/env bash
# header: add, replace, and delete header lines.
# 
# Example usage:
# $ seq 10 | header -a 'values'
# $ seq 10 | header -a 'VALUES' | header -e 'tr "[:upper:]" "[:lower:]"'
# $ seq 10 | header -a 'values' | header -d
# $ seq 10 | header -a 'multi\nline' | header -n 2 -e "paste -sd_"
#
# see also: body
#
# Author: http://jeroenjanssens.com

我该怎么做呢?

我想我可以在多行模式下使用正则表达式提取所有连续匹配的行,但我只想要匹配的第一部分。

更新:

我想要正则表达式^(#.*)|(\s*)$来匹配

  • #行首带有 a 的注释
  • 空行(如 后面的一行# Author
  • 行仅包含空格

答案1

awk

$ awk '/^#/{f=1} f && !/^#|^[[:space:]]*$/{exit} f' ip.txt
#!/usr/bin/env bash
# header: add, replace, and delete header lines.
# 
# Example usage:
# $ seq 10 | header -a 'values'
# $ seq 10 | header -a 'VALUES' | header -e 'tr "[:upper:]" "[:lower:]"'
# $ seq 10 | header -a 'values' | header -d
# $ seq 10 | header -a 'multi\nline' | header -n 2 -e "paste -sd_"
#
# See also: body
#

# Author: http://jeroenjanssens.com

当找到第一个注释时,这将开始提取行,并且只要一行是注释或具有零个或多个空格的行,就会继续打印。

答案2

GNU sed。没有尾随空格:

sed '/^#/,$!d;:1;/^\s*$/N;/\S/!b1;/^#/M!Q' file

/^#/,$!d- 在评论开始之前截断行。
:1;/^\s*$/N;/\S/!b1- 如果有空行或只有空格,则添加到缓冲区(模式空间)。
/^#/M!Q'- 如果遇到不以注释标记开头的行,则退出脚本(M- 锚点在多行缓冲区中有效)。

带有尾随空格:

sed '/^#/,$!d;/^#\|^\s*$/!Q' file

相关内容