首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sed,匹配两个模式之间的所有行(包括),然后将第二个匹配放在顶部。

Sed,匹配两个模式之间的所有行(包括),然后将第二个匹配放在顶部。
EN

Stack Overflow用户
提问于 2021-05-19 21:48:22
回答 3查看 88关注 0票数 1

这就是我需要做的:

输入:(Python)

代码语言:javascript
复制
## This is a function,
## its purpose is... yada yada yada
def function_name(x):
    return x + 1

产出:(减价)

代码语言:javascript
复制
## function_name
This is a function,
its purpose is... yada yada yada

到目前为止我得到了:

代码语言:javascript
复制
sed -n '/## /,/def/ { /## \|def/ p }' TEST.py | cut -d' ' -f2- | sed 's/(.*)\(.*\)://'

它产生:

代码语言:javascript
复制
This is a function,
its purpose is... yada yada yada
function_name

有两个条件:

1.-不匹配这些模式的"##“和"def”之间的行应该被忽略。

示例:

输入:(Python)

代码语言:javascript
复制
## This is a function,
## its purpose is... yada yada yada
# This is a normal comment, nothing to see here! (ignored)
def function_name(x):
    return x + 1

产出:(减价)

代码语言:javascript
复制
## function_name
This is a function,
its purpose is... yada yada yada

2.-第二种模式必须加以推广,例如,不要使用"def",比方说我要使用"class“。

输入:(Python)

代码语言:javascript
复制
## This is a class,
## its purpose is... yada yada yada
# This is a normal comment, nothing to see here! (ignored)
class class_name:
    __init__(self, x):
        self.x = x

产出:(减价)

代码语言:javascript
复制
## class_name
This is a class,
its purpose is... yada yada yada
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-05-19 22:01:18

使用awk

代码语言:javascript
复制
$ awk '/^## / { comment = comment substr($0, 4) "\n" }
       /^def / { printf "## %s\n%s", substr($0, 5, index($0, "(") - 5), comment
                 comment = "" }' TEST.py  
## function_name
This is a function,
its purpose is... yada yada yada

将以##开头的所有行追加到变量中,当它看到以def开头的行时,打印函数名和前面行的变量,然后空白该变量以重新启动。

使用持有空间存储注释行的GNU sed版本:

代码语言:javascript
复制
$ sed -n -e '/^## / { s/^## //; H }' -e '/^def / { s/^def \([^(]*\).*/## \1/; G; s/\n\n/\n/; p; z; x }' TEST.py
## function_name
This is a function,
its purpose is... yada yada yada
票数 3
EN

Stack Overflow用户

发布于 2021-05-19 23:36:17

在每个Unix框上使用任何shell中的任何awk (如果awk不支持POSIX字符类,则使用a-zA-Z0-9而不是[:alnum:] ):

代码语言:javascript
复制
$ cat tst.awk
sub(/^## */,"") {
    cmts = cmts $0 ORS
    next
}

sub(/^[[:alnum:]_]+ */,"") {
    sub(/[^[:alnum:]_].*/,"")
    print "##", $0
    print cmts
    cmts = ""
}
代码语言:javascript
复制
$ awk -f tst.awk file
## function_name
This is a function,
its purpose is... yada yada yada

## function_name
This is a function,
its purpose is... yada yada yada

## class_name
This is a class,
its purpose is... yada yada yada

上面的内容是在这个输入文件上运行的:

代码语言:javascript
复制
$ cat file
## This is a function,
## its purpose is... yada yada yada
def function_name(x):
    return x + 1

## This is a function,
## its purpose is... yada yada yada
# This is a normal comment, nothing to see here! (ignored)
def function_name(x):
    return x + 1

## This is a class,
## its purpose is... yada yada yada
# This is a normal comment, nothing to see here! (ignored)
class class_name:
    __init__(self, x):
        self.x = x
票数 4
EN

Stack Overflow用户

发布于 2021-05-19 22:09:21

代码语言:javascript
复制
awk '
/##/ { 
  gsub( "## *", "" )  
  previous[ ++lines ] = $0 
}
/def/ { 
  gsub( "def ", "")  
  gsub( "[(].*","" ) 
  print "## " $0  
  for (x = 1 ; x <= lines ; x++ ) 
    print previous[x] 
  lines = 0 
}
' TEST.py

看来肖恩比我早找到答案了。答案是相似的,它们的区别主要在于线条是如何累积的。Shawn将前面的行累加在一个变量(注释)中,而我则将其累加到数组中。

我认为Shawn在代码中可能有更多的假设,就像每个##在它之后都有一个空格,或者函数名从一行的第五个字符开始,而##和def都出现在行的开头。

我认为我也应该添加一些锚,因为/def/可能有很多意想不到的匹配,所以/^def/可能要好得多。

有趣的是,我们都忽略了使用sed,因为我个人不知道如何处理sed中的变量。我感兴趣的是,其他解决方案是否可以从纯sed社区获得。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67611344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档