ファイルから連続的に一致する行の最初のブロックを抽出しますか?

ファイルから連続的に一致する行の最初のブロックを抽出しますか?

だから、次のファイルがあります。

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*)$一致するファイルの最初の行から正規表現に一致するすべての行を抽出したいと思います。続けて一致する最後の行まで。

予想される抽出結果は次のとおりです。


#!/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*)$正規表現が一致したい

  • #行の先頭にコメントがある場合
  • 空の行(例:次の行# 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

最初のコメントが見つかると、行の抽出が開始され、行がコメントであるか空白が0個以上ある限り印刷されます。

答え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

関連情報