我有一个函数,它应该在特定行号之间获取行,传递给它并存储在变量中,以及带有'endhelp'模式的下一行
我现在的代码:
START_LINE=$1 #-- On which line the help is and where the search should start
#-- Where the help command block ends
END_LINE[1]=$(sed -n "$START_LINE,/endhelp/p=" filename)
#-- Add one number to END_LINE as a second array value to speed line extracting
END_LINE[2]=$((${END_LINE[1]}+1))
#-- The actual line extraction that outputs the whole lines
sed -n "$START_LINE,${END_LINE[1]}p; ${END_LINE[2]}q" filename
所以,如果我有这样的东西:(注意:输入文件中还有其他类似的块,所以这就是起始线很重要的原因)
-- some text --
help
text and some more text
more words and text
third help thing line
stuff
hi
endhelp
-- some other text --
输出结果为:
text and some more text
more words and text
third help thing line
stuff
hi
上述代码是否有效并且可以更有效地完成吗?还有如何在检测到只有字符串'endhelp'的空行时停止?
更新
以下是执行我想要的更新代码:
START_LINE=$2 #-- Where the help command block starts
awk 'BEGIN {OUTPUT=0} NR=='$START_LINE' {OUTPUT=1} /^endhelp$/ {exit} OUTPUT'
如果行只有字符串'endhelp'并从$ START_LINE开始打印,它就会停止。我添加了BEGIN {OUTPUT=0}
,因为它在某些旧设备上出现了错误。
UPDATE2
我再次编辑了代码,如果在“START_LINE”之前在其他空行上看到“endhelp”,则将其修复退出:
awk 'NR>='$START_LINE' {if ($0 ~ /^endhelp$/) {exit} else {$1=$1; print}}'
它更小,速度更快。它还添加了$1=$1
,它从当前行中删除尾随和前导空格。如果不需要,可以安全地删除它。
答案 0 :(得分:2)
可以更高效地完成吗?还有如何在检测到只有字符串'endhelp'的空行时停止?
这是一个比你的脚本更有效的awk版本:
awk -v n=$1 '/^endhelp$/{exit} p; NR==n || /^help$/{p=1}' file
这将从给定的行号开始打印,或者当行中只有help
文本时打印。它将继续打印,直到显示endhelp
文本的行。此时awk
只会exit
,文件的其余部分将不会被处理。
答案 1 :(得分:1)
如果您已经在搜索起始线,为什么不在这些锚之间打印?
以Perl为例:
$ echo "$help_text"
help 1
text 1 and some more text
more words and text
third help thing line
stuff
hi
endhelp
help 2
text 2 and some more text
more words and text
third help thing line
stuff
hi
endhelp
help 3
text 3 and some more text
more words and text
third help thing line
stuff
hi
endhelp
您可以在锚点help \d
和endhelp
之间打印文字,如下所示:
$ echo "$help_text" | perl -0777 -ne 'print $1 if /^help[ \t]+3(.*?)^endhelp/ms'
text 3 and some more text
more words and text
third help thing line
stuff
hi
在awk中:
$ echo "$help_text" | awk '
> /^help 3/ {flag=1; next}
> /^endhelp/ {flag=0}
> flag {print}'
text 3 and some more text
more words and text
third help thing line
stuff
hi
如果您使用行号作为块的开头,则可以执行以下操作:
$ echo "$help_text" | awk '
NR==17 {flag=1; next}
/^endhelp/ {flag=0}
flag {print}'
text 3 and some more text
more words and text
third help thing line
stuff
hi
答案 2 :(得分:0)
我宁愿使用awk
oneliner来提取您需要的行:
awk "NR==$1 && /help/ {flag=1;next}/endhelp/{flag=0}flag" filename
输入文件名和NR == 3:
-- some text --
help
text and some more text
more words and text
third help thing line
stuff
hi
endhelp
-- some other text --
输出:
text and some more text
more words and text
third help thing line
stuff
hi
您也可以这样做,只需指定行号:
awk "NR==$1 {flag=1;next}/endhelp/{flag=0}flag" filename