使用 grep 从文件中匹配 python 多行表达式字符串?
matching python multiline expression string from a file using grep?
请注意,这不是 python 问题。我有多个目录(大约 500 个目录,称为模块),每个目录包含一个 __manifest__.py
文件。该文件被视为模块的元数据。该文件如下所示:
{
'name': 'Associations Management',
'version': '0.1',
'category': 'Marketing',
'depends': [
'base_setup',
'membership',
'event'
],
'data': ['views/views.xml'],
'demo': [],
'installable': True,
'auto_install': False,
}
我想匹配并提取(仅使用 Linux shell)一个可能如下的模式:
'depends': ['base', 'web],
// or multi-line as
"depends": [
'base',
'web',
]
我真的对使用 Linux 命令提取此类信息很感兴趣,例如 grep
或 sed
或 awk
我对使用 Linux 评估每个文件不感兴趣python 翻译。所以我使用了以下 Linux 命令
find . -iname __manifest__.py | xargs -I{} grep -H -E "('|\")depends('|\")(.?|\n)*\]\s*," {}
但是我的正则表达式没有为我提供多行选择。我也担心匹配更多不需要的行如下:
'depends': [
'base_setup',
'membership',
'event'
],
'data': ['views/views.xml'],
谢谢
与GNU grep
$ grep -zoE "'depends'"':\s*\[[^][]+]' ip.txt | tr '[=10=]' '\n'
'depends': [
'base_setup',
'membership',
'event'
]
-z
选项将导致 grep
使用 ASCII NUL 字符作为分隔符。因此,假设您的输入文件没有此字符,实际上这意味着输入被读取为单个字符串
-o
只得到匹配的部分
"'depends'"':\s*\[[^][]+]'
将匹配 'depends':
后跟可选的空格后跟 [
字符后跟一个或多个非 []
字符后跟 ]
- 这意味着任何嵌套的
[]
序列都不适合此解决方案
tr '[=23=]' '\n'
将 NUL 字符转换为换行符,因为 -z
也意味着 NUL 作为输出中的分隔符
与ripgrep:
$ rg -oUN "'depends'"':\s*\[[^\]\[]+]' ip.txt
'depends': [
'base_setup',
'membership',
'event'
]
优点是这不依赖于 NUL 字符,也不必一次读取整个输入。 -U
是多行匹配选项,-N
关闭行号前缀(终端输出默认打开)。此外,GNU grep
和 rg
都支持递归搜索。
如果你要匹配的数据总是整行,'depends': [
在一行中,你也可以使用awk
。有关解释,请参阅 。
$ awk '/7depends7:[[:blank:]]*\[/{f=1} f; /]/{f=0}' ip.txt
'depends': [
'base_setup',
'membership',
'event'
],
请注意,这不是 python 问题。我有多个目录(大约 500 个目录,称为模块),每个目录包含一个 __manifest__.py
文件。该文件被视为模块的元数据。该文件如下所示:
{
'name': 'Associations Management',
'version': '0.1',
'category': 'Marketing',
'depends': [
'base_setup',
'membership',
'event'
],
'data': ['views/views.xml'],
'demo': [],
'installable': True,
'auto_install': False,
}
我想匹配并提取(仅使用 Linux shell)一个可能如下的模式:
'depends': ['base', 'web],
// or multi-line as
"depends": [
'base',
'web',
]
我真的对使用 Linux 命令提取此类信息很感兴趣,例如 grep
或 sed
或 awk
我对使用 Linux 评估每个文件不感兴趣python 翻译。所以我使用了以下 Linux 命令
find . -iname __manifest__.py | xargs -I{} grep -H -E "('|\")depends('|\")(.?|\n)*\]\s*," {}
但是我的正则表达式没有为我提供多行选择。我也担心匹配更多不需要的行如下:
'depends': [
'base_setup',
'membership',
'event'
],
'data': ['views/views.xml'],
谢谢
与GNU grep
$ grep -zoE "'depends'"':\s*\[[^][]+]' ip.txt | tr '[=10=]' '\n'
'depends': [
'base_setup',
'membership',
'event'
]
-z
选项将导致grep
使用 ASCII NUL 字符作为分隔符。因此,假设您的输入文件没有此字符,实际上这意味着输入被读取为单个字符串-o
只得到匹配的部分"'depends'"':\s*\[[^][]+]'
将匹配'depends':
后跟可选的空格后跟[
字符后跟一个或多个非[]
字符后跟]
- 这意味着任何嵌套的
[]
序列都不适合此解决方案
- 这意味着任何嵌套的
tr '[=23=]' '\n'
将 NUL 字符转换为换行符,因为-z
也意味着 NUL 作为输出中的分隔符
与ripgrep:
$ rg -oUN "'depends'"':\s*\[[^\]\[]+]' ip.txt
'depends': [
'base_setup',
'membership',
'event'
]
优点是这不依赖于 NUL 字符,也不必一次读取整个输入。 -U
是多行匹配选项,-N
关闭行号前缀(终端输出默认打开)。此外,GNU grep
和 rg
都支持递归搜索。
如果你要匹配的数据总是整行,'depends': [
在一行中,你也可以使用awk
。有关解释,请参阅
$ awk '/7depends7:[[:blank:]]*\[/{f=1} f; /]/{f=0}' ip.txt
'depends': [
'base_setup',
'membership',
'event'
],