Bash在带有Regex和变量的模式之间删除

Bash在带有Regex和变量的模式之间删除,regex,bash,awk,sed,Regex,Bash,Awk,Sed,我需要根据模式删除txt文件中的所有引用。模式的一部分是一个变量 以下是txt文件的外观: #start_pattern_dhhr6783-rhr.variable.1# some line here some other line here some other line here new line goes here #end_pattern_dhhr6783-rhr.variable.1 #start_pattern_variable.2# some l

我需要根据模式删除txt文件中的所有引用。模式的一部分是一个变量

以下是txt文件的外观:

#start_pattern_dhhr6783-rhr.variable.1#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_dhhr6783-rhr.variable.1

#start_pattern_variable.2#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_variable2

#start_pattern_7hbdhy-hjruy_hry673.variable.3#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_7hbdhy-hjruy_hry673.variable.3

#start_pattern_variable.4#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_variable4

#start_pattern_variable.3#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_variable.3

#start_pattern_498595-hjfufr7.variable.3#
some line here     
    some other line here
    some other line here
    new line goes here
#end_pattern_498595-hjfufr7.variable.3
以下是我试图做的:

pattern="variable.3"

sed -n "/^#start*$pattern/,/^#end*$pattern/d"  /root/file.txt
sed -n "/#start*$pattern/,/#end*$pattern/d"  /root/file.txt
sed -n "/^#start*\$pattern/,/^#end*\$pattern/d"  /root/file.txt
sed -n "/^#start.*$pattern/,/^#end.*$pattern/d"  /root/file.txt
sed -n '/^#start*"$pattern"/,/^#end*"$pattern"/d'  /root/file.txt
sed -n '/^#start_pattern_*"$pattern"/,/^#end_pattern_*"$pattern"/d'  /root/file.txt
但它们都不起作用。输出和以前一样,所以什么也没发生。已经在3台linux机器上尝试过了,但是没有发生任何事情,没有对文件进行任何修改

我想要的是删除包含变量“variable.3”的模式之间的所有匹配项

它应该匹配所有这3个结果:

#start_pattern_7hbdhy-hjruy_hry673.variable.3#....

#start_pattern_variable.3#....

#start_pattern_498595-hjfufr7.variable.3#....

下面的
awk
可能会在同样的情况下帮助您。这将删除模式之间的行,也将从输出中删除空行

awk -v val="variable.3" '
/#start/ && $0 ~ val{
  no_print=1
}
/#start/ && $0 !~ val{
  no_print=""
}
!no_print && NF
'   Input_file
输出如下

    #start_pattern_dhhr6783-rhr.variable.1#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_dhhr6783-rhr.variable.1
    #start_pattern_variable.2#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_variable2
    #start_pattern_variable.4#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_variable4
您可以在
-v val
中给出变量的值,以便根据需要进行更改。另外,如果输出中需要空行,则需要更改条件
!没有打印和打印到
!没有打印
,它应该会飞起来

可以将
$0~val
更改为
索引($0,val)
,以避免错误匹配。感谢埃德·莫顿先生的意见。更多细节可以在这篇文章的评论部分找到

解释:现在也添加代码解释:

awk -v val="variable.3" '    ##Setting variable named val value to variable.3 here.
/#start/ && $0 ~ val{        ##Checking condition here if a line is having string #start in it and it is having variable val in it too then do following:
  no_print=1                 ##Setting variable named no_print value to TRUE.
}
/#start/ && $0 !~ val{       ##Checking condition here if a line is having string #start and it is NOT having variable val in it then do following:
  no_print=""                ##Setting variable no_print to NULL here.
}
!no_print && NF              ##Checking condition here if variable no_print is NULL and NF(number of fields in a line, awk out of the box variable) is NOT NULL
                             ##then print those lines, basically this condition is to print those lines which are NOT coming in the block of variable pattern.
' Input_file                 ##Mentioning the Input_file name here.

下面的
awk
可能会在同样的情况下帮助您。这将删除模式之间的行,也将从输出中删除空行

awk -v val="variable.3" '
/#start/ && $0 ~ val{
  no_print=1
}
/#start/ && $0 !~ val{
  no_print=""
}
!no_print && NF
'   Input_file
输出如下

    #start_pattern_dhhr6783-rhr.variable.1#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_dhhr6783-rhr.variable.1
    #start_pattern_variable.2#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_variable2
    #start_pattern_variable.4#
    some line here
    some other line here
    some other line here
    new line goes here
    #end_pattern_variable4
您可以在
-v val
中给出变量的值,以便根据需要进行更改。另外,如果输出中需要空行,则需要更改条件
!没有打印和打印到
!没有打印
,它应该会飞起来

可以将
$0~val
更改为
索引($0,val)
,以避免错误匹配。感谢埃德·莫顿先生的意见。更多细节可以在这篇文章的评论部分找到

解释:现在也添加代码解释:

awk -v val="variable.3" '    ##Setting variable named val value to variable.3 here.
/#start/ && $0 ~ val{        ##Checking condition here if a line is having string #start in it and it is having variable val in it too then do following:
  no_print=1                 ##Setting variable named no_print value to TRUE.
}
/#start/ && $0 !~ val{       ##Checking condition here if a line is having string #start and it is NOT having variable val in it then do following:
  no_print=""                ##Setting variable no_print to NULL here.
}
!no_print && NF              ##Checking condition here if variable no_print is NULL and NF(number of fields in a line, awk out of the box variable) is NOT NULL
                             ##then print those lines, basically this condition is to print those lines which are NOT coming in the block of variable pattern.
' Input_file                 ##Mentioning the Input_file name here.

你的方法让事情变得更加复杂。您真正需要的是:

awk -v RS= -v ORS='\n\n' -F'\n' -v str='variable.3' '!index($1,str)' file

请注意,上述方法也比使用regexp更健壮,因为regexp需要转义搜索字符串中的元字符(例如
)。

您的方法使其变得比必须的复杂得多。您真正需要的是:

awk -v RS= -v ORS='\n\n' -F'\n' -v str='variable.3' '!index($1,str)' file

请注意,上述方法也比使用regexp更可靠,因为regexp需要转义搜索字符串中的元字符(例如,
)。

仅代码格式,示例在#开始和#结束标记前没有空格。在这种上下文中,不要使用单词
模式
,因为它不明确。始终使用
string
regexp
这个词,以您真正的意思为准。在您的情况下,您不希望
变量.3
中的
被视为regexp元字符,因此显然您的意思是搜索字符串,而不是regexp。由于sed不能搜索字符串,只能搜索regexp,因此您不应考虑使用sed执行此任务,请改用awk(它支持字符串操作)。可能只会重复代码格式,示例的#开始和#结束标记前没有空格。在本上下文中,请不要使用单词
模式
,因为它不明确。始终使用
string
regexp
这个词,以您真正的意思为准。在您的情况下,您不希望
变量.3
中的
被视为regexp元字符,因此显然您的意思是搜索字符串,而不是regexp。由于sed不能搜索字符串,只能搜索regexp,因此您不应该考虑使用sed来执行此任务,而是使用awk(它支持字符串操作)。可能与@RavinderSingh13重复:很好的解释,有一件事要问。
no_print
在脚本中的作用是什么,它是
awk
的实用程序还是定义为打印或不打印行的单独变量?@User123,谢谢。不,如解释中所述,它是awk程序中使用的变量。因此,顾名思义,当它的值为真时,它不会打印行。由于使用regexp而不是字符串比较,这将产生错误匹配。@EdMorton,当然是Ed先生,希望您能用正确的值编辑它,或者在这里指导我,将
$0~val
更改为
索引($0,val)
,或者提供一种机制来转义
val
中所有可能的regexp元字符(不推荐!),或者在调用脚本之前告诉OP手动转义regexp元字符。@RavinderSingh13:很好的解释,有一件事要问。
no_print
在脚本中的作用是什么,它是
awk
的实用程序还是定义为打印或不打印行的单独变量?@User123,谢谢。不,如解释中所述,它是awk程序中使用的变量。因此,顾名思义,当它的值为真时,它不会打印行。由于使用regexp而不是字符串比较,这将产生错误匹配。@EdMorton,当然是Ed先生,希望您能用正确的值编辑它,或者在这里指导我,将
$0~val
更改为
索引($0,val)
,或者提供一种机制来转义
val
中所有可能的regexp元字符(不推荐!),或者在调用脚本之前告诉OP手动转义regexp元字符。