Regex 如果遇到其他几个节头中的任何一个,如何退出Sed中的节模式匹配?
我正在使用Regex 如果遇到其他几个节头中的任何一个,如何退出Sed中的节模式匹配?,regex,bash,sed,pattern-matching,editing,Regex,Bash,Sed,Pattern Matching,Editing,我正在使用sed内联编辑开放标准多节、空格分隔文件中特定节中的特定条目,该文件对某些数值常量进行编码 我有一个工作表达式来实现这一点,但我另外希望它在到达另一个节标题时能够退出,而没有找到与内部模式匹配的内容,因为根据标准,理论上这些节可能会出现故障,并且我要查找的标签/模式可能与文件的其他节匹配 文件规范的抽象版本以部分标题开始,标题作为标题关键字字符串列表,即平面,列车,汽车,总线``潜艇。要进行标识,标题关键字字符串必须位于行的开头,并且必须后跟空白字符(空格或制表符)。该行或下一行上可能
sed
内联编辑开放标准多节、空格分隔文件中特定节中的特定条目,该文件对某些数值常量进行编码
我有一个工作表达式来实现这一点,但我另外希望它在到达另一个节标题时能够退出,而没有找到与内部模式匹配的内容,因为根据标准,理论上这些节可能会出现故障,并且我要查找的标签/模式可能与文件的其他节匹配
文件规范的抽象版本以部分标题开始,标题作为标题关键字字符串列表,即平面
,列车
,汽车
,总线``潜艇
。要进行标识,标题关键字字符串必须位于行的开头,并且必须后跟空白字符(空格或制表符)。该行或下一行上可能会有其他空格分隔的特定于节的参数,尽管大多数节没有这些参数。空行被忽略,因此可用于提高可读性,但不能假设。在“!”之后有什么事吗或“*”假定为注释。在一个部分中,N个公共属性关键字(例如小的
,中的
,大的
,大的
)的某个给定组合的一组常量由后面的数字常量(例如##########
)定义。属性关键字在多个节中使用,但不能保证在特定节中找到
例如:
*
* Header comments
*
PLANES
!
! COMMENTS
!
BIG MEDIUM ##.### ##.###
BIG SMALL ##.### ##.###
...
SMALL SMALL ##.### ##.###
THE_TRAINS
!
! COMMENTS
!
MEDIUM MEDIUM SMALL ##.### ##.### ! COMMENT STUFF
MEDIUM SMALL SMALL ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG ##.### ##.###
AN_AUTOMOBILE 0.1 shift red
!
! COMMENTS
SMALL SMALL SMALL SMALL ##.### ##.### ##.###
SMALL MEDIUM SMALL SMALL ##.### ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG SMALL ##.### ##.### ##.###
BUSES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
LARGE ##.### ##.### ## !
SUBMARINES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
HUGE ##.### ##.### ## !
在*
或之后的任何内容代码>在文件标准中被视为注释
节是通过遇到后跟空格的关键字来定义的。在此之后,可能会有特定于节的填充变量(请参见编辑的示例中的shift
),但最终每个节都有一个数字常量列表,前面有一组N个标识符,这些标识符对所有节都是通用的
节之间或节内各行之间的空白是任意的,可以添加以提高可读性,但不能假定
如果排序与我的当前文件相同,则模式为:
sed -i '/SUBMARINES/{:keep_reading;n; /^MEDIUM.*$/!bkeep_reading s/^MEDIUM.*$/DERP/ }' file.dat
…有效
如果上述表达式不清楚我的预期操作,我的目标是替换以某个给定关键字(即潜艇[\t]
)为首的小节中的某些模式(即^MEDIUM.*$
)。在本例中,我只是将整个匹配线替换为DERP
。在实际的实现中,我会做一个特定于实现的替换,但我已经知道如何做了,它的细节对于如何在sed中使用内置的微语言来尝试达到这一点是多余的,如果遇到其他子部分而在目标子部分中找不到匹配项,则退出
但是,如果部分出现故障,它可能会再次中断(即,如果我尝试替换总线中的巨型
,它将继续到下一小节,潜艇
,并替换该小节,因为在给定部分中找不到该小节)
在遇到给定的章节标题关键字后加空格/制表符(即潜艇[\t]
),如果我遇到任何其他章节标题/副标题(即飞机
,公共汽车
,汽车
,以及火车
),我该如何摆脱
这将防止在潜艇
中替换以巨型
开头的线路,而我的意图是仅在总线
中找到以巨型
开头的线路时才替换该线路
编辑1:
我想是这样的:
sed -i '/BUSES/{:keep_reading;n; /^HUGE.*$/!bkeep_reading /PLANES/\|/THE_TRAINS/\|/AN_AUTOMOBILE/\|/SUBMARINES/q s/^HUGE.*$/DERP/g }' file.dat
。。。可以工作,但该表达式给出了错误:
sed:-e表达式#1,字符60:未知命令:`'
编辑2:
我有一个半工作的解决方案:
sed -i '/BUSES/{:keep_reading;n; /^PLANES[ \t]\|^THE_TRAINS[ \t]\|^AN_AUTOMOBILE[ \t]\|^BUSES[ \t]/q; /^HUGE.*$/!bkeep_reading; s/^HUGE.*$/DERP/g; }' file.dat
但我现在意识到,我以前的两种解决方案实际上都会在内联编辑时删除maging
之后的任何行。我没有意识到这一点,因为我匹配的标签恰好是文件中的最后一行
上述模式正确退出,但会截断文件的其余部分。这似乎是一个简单的解决方案--如何保持文件的其余部分不变
另外,如果使用了这种附加语法,是否有更好的工具可以从命令行使用(例如perl、python等?地址范围:
sed -i '/^SUB_HEADING_II$/,/^[A-Z_]\+$/{ s/^LBL_B1.*$/DERP/g }' file
替换将应用于子标题_II
和下一行(包含大写字符和下划线的混合)之间的行。在查找by之后的
如果要将以LBL\u B1
开头的行更改为以SUB\u HEADING\u II
或SUB\u HEADING\u IV
(但不是SUB\u HEADING\u III
)开头的块中的DERP
,则在任何版本的sed
中都可以执行此操作(尽管它不会覆盖原始文件):
对于子目II
或IV
(我使用了符号的重合紧凑性)至空行(或EOF)范围内的行,用DERP
替换行开头的LBL_B1
如果副标题更加多样化,则:
sed -e '/^SUB_HEADING_IV$/,/^$/ s/^LBL_B1.*/DERP/' \
-e '/^DIVERSITY_REIGNS$/,/^$/ s/^LBL_B1.*/DERP/'
如果您激活扩展正则表达式(-r
在GNUsed
中,-E
在BSD或Mac OS Xsed
),那么您可以使用(BSD表示法,但这里唯一的区别是-E
与-r
):
这假设在副标题行上没有注释。如果可以发表评论,您必须在识别起始行的正则表达式上更加努力:
sed -E '/^(SUB_HEADING_IV|DIVERSITY_REIGNS)( *!.*)?$/,/^$/ s/^LBL_B1.*/DERP/'
我不清楚是否可以用*
来开始“尾部评论”;如果是,请更换代码>与[!*]
一起使用
在找到后面的
sed -E '/^(SUB_HEADING_IV|DIVERSITY_REIGNS)$/,/^$/ s/^LBL_B1.*/DERP/'
sed -E '/^(SUB_HEADING_IV|DIVERSITY_REIGNS)( *!.*)?$/,/^$/ s/^LBL_B1.*/DERP/'
sed -E '/^(SUB_HEADING_II|SUB_HEADING_IV)$/,/^(SUB_HEADING_I|SUB_HEADING_II|SUB_HEADING_III|SUB_HEADING_IV)$/ {
s/^LBL_B1.*/DERP/; }'
SH=( "SUB_HEADING_I" "THE_AUTOMOBILE" "A_SUBMARINE" "SUB_HEADING_II"
"TRANSVERSE_COGITATION" "DIAMETRICALLY_OPPOSED" "SUB_HEADING_III"
"CODSWALLOP" "SUB_HEADING_IV"
)
EH="$(IFS="|"; echo "/^(${SH[*]})\$/")"
sed -E '/^(SUB_HEADING_II|SUB_HEADING_IV)( *[!*].*)?$/,'"$EH"' s/^LBL_B1.*/DERP/'
SH=( "PLANES" "THE_TRAINS" "AN_AUTOMOBILE" "BUSES" "SUBMARINES" )
EH="$(IFS="|"; echo "/^(${SH[*]})([ !*].*)?$/")"
sed -E '/^BUSES([ !*].*)?$/,'"$EH"' s/^HUGE.*/DERP/' data
SH=( "PLANES" "THE_TRAINS" "AN_AUTOMOBILE" "BUSES" "SUBMARINES" )
EH="$(IFS="|"; echo "/^(${SH[*]})([ !*].*)?\$/")"
sed -E '/^SUBMARINES([ !*].*)?$/,'"$EH"' s/^HUGE.*/DERP/' data
$ bash -x script.sh
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ SH=("PLANES" "THE_TRAINS" "AN_AUTOMOBILE" "BUSES" "SUBMARINES")
++ IFS='|'
++ echo '/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/'
+ EH='/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/'
+ sed -E '/^BUSES([ !*].*)?$/,/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/ s/^HUGE.*/DERP/' data
*
* Header comments
*
PLANES
!
! COMMENTS
!
BIG MEDIUM ##.### ##.###
BIG SMALL ##.### ##.###
...
SMALL SMALL ##.### ##.###
THE_TRAINS
!
! COMMENTS
!
MEDIUM MEDIUM SMALL ##.### ##.### ! COMMENT STUFF
MEDIUM SMALL SMALL ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG ##.### ##.###
AN_AUTOMOBILE 0.1 shift red
!
! COMMENTS
SMALL SMALL SMALL SMALL ##.### ##.### ##.###
SMALL MEDIUM SMALL SMALL ##.### ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG SMALL ##.### ##.### ##.###
BUSES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
LARGE ##.### ##.### ## !
SUBMARINES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
HUGE ##.### ##.### ## !
+ SH=("PLANES" "THE_TRAINS" "AN_AUTOMOBILE" "BUSES" "SUBMARINES")
++ IFS='|'
++ echo '/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/'
+ EH='/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/'
+ sed -E '/^SUBMARINES([ !*].*)?$/,/^(PLANES|THE_TRAINS|AN_AUTOMOBILE|BUSES|SUBMARINES)([ !*].*)?$/ s/^HUGE.*/DERP/' data
*
* Header comments
*
PLANES
!
! COMMENTS
!
BIG MEDIUM ##.### ##.###
BIG SMALL ##.### ##.###
...
SMALL SMALL ##.### ##.###
THE_TRAINS
!
! COMMENTS
!
MEDIUM MEDIUM SMALL ##.### ##.### ! COMMENT STUFF
MEDIUM SMALL SMALL ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG ##.### ##.###
AN_AUTOMOBILE 0.1 shift red
!
! COMMENTS
SMALL SMALL SMALL SMALL ##.### ##.### ##.###
SMALL MEDIUM SMALL SMALL ##.### ##.### ##.### ! COMMENT STUFF
...
BIG BIG BIG SMALL ##.### ##.### ##.###
BUSES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
LARGE ##.### ##.### ## !
SUBMARINES
SMALL ##.### ##.### ## !
MEDIUM ##.### ##.### ## !
...
DERP
$