使用 bash(正则表达式,sed)删除模式之间的分隔代码块
Removing delimited block of code between patterns using bash (regex, sed)
我有一个包含 visibility
声明的文件,跨越一行或多行,我想删除 仅 如果它们在 test
块中.
即input.txt:
test(
srcs = [
"test1",
],
visibility = [
"common",
],
deps = [ "deps" ],
)
test(
srcs = [
"test2",
],
visibility = [ "common" ],
)
即输出:
test(
srcs = [
"test1",
],
deps = [ "deps" ],
)
test(
srcs = [
"test2",
],
)
可见性线可能在其他块内,即 etc(...)
,在这种情况下不应删除它们。即:
etc(
src = [
"etc",
],
# should not be removed because it's not inside a test(...) block
visibility = [
"common",
],
)
这是我尝试过的方法,但是,这只匹配跨越单行的 visibility
个块:
#!/bin/bash
#remove_lines.sh
remove_visibility_lines () {
start_pattern="test"
end_pattern=")"
pattern_to_remove="visibility = \[.*\],"
sed "/${start_pattern}/,/${end_pattern}/{/${pattern_to_remove}/d}" ""
}
remove_visibility_lines
$ ./remove_lines.sh input.txt
我已经尝试了几种方法来消除跨越多个块的可见性,即 (.*?)
和 (\_.*)
,但我似乎无法让它工作。
请帮忙?
问题类似于:
Using sed to delete all lines between two matching patterns ,但是,在我的例子中,我有嵌套在模式中的模式。即:您只查看 test(...)
块内部,并且仅在这些块内部删除 visibility = [...],
块。
使用 awk
,假设没有嵌套 ()
个字符:
awk '/^test\(/{f=1} [=10=]==")"{f=0}
f && /visibility = \[/{v=1} !v; /],/{v=0}' ip.txt
/^test\(/{f=1}
如果一行以 test(
开头,则设置标志 f
[=17=]==")"{f=0}
清除标记 f
如果一行仅包含 )
f && /visibility = \[/{v=1}
设置标志 v
如果 f
也被设置并且一行包含 visibility = [
!v;
仅在未设置标志 v
时打印输入行
/],/{v=0}
清除标记 v
如果行包含 ],
要传递开始和结束字符串:
$ cat script.awk
index([=11=], start) == 1 { f = 1 }
[=11=] == end { f = 0 }
f && /visibility = \[/ { v = 1 }
! v { print }
/],/ { v = 0 }
$ awk -v start='test(' -v end=')' -f script.awk ip.txt
我有一个包含 visibility
声明的文件,跨越一行或多行,我想删除 仅 如果它们在 test
块中.
即input.txt:
test(
srcs = [
"test1",
],
visibility = [
"common",
],
deps = [ "deps" ],
)
test(
srcs = [
"test2",
],
visibility = [ "common" ],
)
即输出:
test(
srcs = [
"test1",
],
deps = [ "deps" ],
)
test(
srcs = [
"test2",
],
)
可见性线可能在其他块内,即 etc(...)
,在这种情况下不应删除它们。即:
etc(
src = [
"etc",
],
# should not be removed because it's not inside a test(...) block
visibility = [
"common",
],
)
这是我尝试过的方法,但是,这只匹配跨越单行的 visibility
个块:
#!/bin/bash
#remove_lines.sh
remove_visibility_lines () {
start_pattern="test"
end_pattern=")"
pattern_to_remove="visibility = \[.*\],"
sed "/${start_pattern}/,/${end_pattern}/{/${pattern_to_remove}/d}" ""
}
remove_visibility_lines
$ ./remove_lines.sh input.txt
我已经尝试了几种方法来消除跨越多个块的可见性,即 (.*?)
和 (\_.*)
,但我似乎无法让它工作。
请帮忙?
问题类似于:
Using sed to delete all lines between two matching patterns ,但是,在我的例子中,我有嵌套在模式中的模式。即:您只查看 test(...)
块内部,并且仅在这些块内部删除 visibility = [...],
块。
使用 awk
,假设没有嵌套 ()
个字符:
awk '/^test\(/{f=1} [=10=]==")"{f=0}
f && /visibility = \[/{v=1} !v; /],/{v=0}' ip.txt
/^test\(/{f=1}
如果一行以test(
开头,则设置标志 [=17=]==")"{f=0}
清除标记f
如果一行仅包含)
f && /visibility = \[/{v=1}
设置标志v
如果f
也被设置并且一行包含visibility = [
!v;
仅在未设置标志v
时打印输入行/],/{v=0}
清除标记v
如果行包含],
f
要传递开始和结束字符串:
$ cat script.awk
index([=11=], start) == 1 { f = 1 }
[=11=] == end { f = 0 }
f && /visibility = \[/ { v = 1 }
! v { print }
/],/ { v = 0 }
$ awk -v start='test(' -v end=')' -f script.awk ip.txt