我有一个像这样的.env文件:
$ cat .env
# My doc for the first var.
FOO_BAR_BAZ1=val1
# My doc for the second var.
# This also spans more than one line.
FOO_BAR_BAZ2=val2
FOO_BAR_BAZ3=val3
当我运行这样的命令时:
$ grep -i "FOO_[^_]*_BAZ*" .env
我希望显示匹配的行,包括前面带有#
前缀的行。
知道我怎么能这样做吗?
答案 0 :(得分:2)
这只打印匹配的行和前面的注释:
awk '/^#/{c = c $0 "\n"; next} /regex_to_match/{print c $0 "\n"} {c=""}' filename
例如:
$ awk '/^#/{c = c $0 "\n"; next} /^FOO_[^_]*_BAZ2/{print c $0 "\n"} {c=""}' .env
# My doc for the second var.
# This also spans more than one line.
FOO_BAR_BAZ2=val2
或:
$ awk '/^#/{c = c $0 "\n"; next} /^FOO_[^_]*_BAZ./{print c $0 "\n"} {c=""}' .env
# My doc for the first var.
FOO_BAR_BAZ1=val1
# My doc for the second var.
# This also spans more than one line.
FOO_BAR_BAZ2=val2
FOO_BAR_BAZ3=val3
/^#/{c = c $0 "\n"; next}
如果此行以#
开头,则将其添加到带有尾随换行符的字符串变量c
。然后跳过其余命令并跳转到next
行。
/regex_to_match/{print c $0 "\n"}
如果此行与正则表达式匹配,则打印评论c
,当前行$0
,并将项目与额外换行符\n
分开。如果您不喜欢额外的换行符,可以将其删除。
c=""
如果我们到达这里,那么这一行不是另一个注释行,因此我们到达了注释块的末尾。要准备下一个注释块,c
将设置为空字符串。
此版本不区分大小写,并且还允许在脚本的命令行上指定正则表达式:
$ cat script
#!/bin/sh
awk -v x="$1" 'BEGIN{IGNORECASE=1} /^#/{c = c $0 "\n"; next} $0 ~ "^Foo_"x"_" {print c $0 "\n"} {c=""}' .env
作为使用此脚本的示例:
$ sh script 'BA.*'
# My doc for the first var.
FOO_BAR_BAZ1=val1
# My doc for the second var.
# This also spans more than one line.
FOO_BAR_BAZ2=val2
FOO_BAR_BAZ3=val3
Unix有两种非常不同的表达模式的样式:globs和正则表达式。以globs为例,BAZ*
匹配BAZ
后跟零个或多个其他任何字符。 Awk不使用globs;它使用正则表达式。在正则表达式中,BAZ*
匹配BA
后跟零个或多个Z
个字符。