【发布时间】:2022-11-16 04:54:40
【问题描述】:
我有一个很长的配置文件,看起来像:
<some stuff before our example>
'Realtime' => [
'foo' => 'bar',
'enabled' => true,
'lorem' => 'ipsum'
],
<some stuff after our example>
上面是一个大型配置 php 文件,我被要求使用 bash 挖掘“实时”的 enabled 值。我可以用 PHP 来做,但我被特别要求用 bash 来做。
我尝试了以下内容:
echo $(tr '\n' ' ' < myconfig.php | sed '$s/ $/\n/') | grep -o -P '(?<=Realtime).*(?=\])'
这会从 Realtime 之间的文件中挖掘文本最后一个]。但是我想挖掘Realtime和第一个]之间的内容。目前我已经实现了一个简单的 bash 并伴随着 PHP 解析器,如下所示:
public function getConfig($name)
{
$path = Paths::CONFIG_FILE;
if (!$this->config) {
$this->config = Command_ShellFactory::makeForServer('zl', "cat {$path}")->execute(true, true);
}
$splitName = explode('.', $name);
$lastPosition = 0;
$tempConfig = $this->config;
foreach ($splitName as $currentName) {
if (($position = strpos($tempConfig, $currentName)) === false) {
throw new RuntimeException('Setting was not found');
}
$tempConfig = substr($tempConfig, $position);
}
return trim(explode("=>", explode("\n", $tempConfig)[0])[1], ", \n\r\t\v\x00");
}
这可行,但我对它不满意,因为它通过 shell 命令将整个文件加载到内存中,然后搜索嵌套键(Realtime.enabled 传递给它)。是否有可能以所有逻辑都通过 bash 发生而不是通过 PHP 帮助它的方式改进此代码?
编辑
要挖掘的可能设置可以是任何深度。例子:
[
/*...*/
'a' => 'b', //Depth of 1
'c' => [
'a' => 'd' //Depth of 2
],
'e' => [
'f' => [
'g' =>'h' //Depth of 3
]
]
/*...*/
]
理论上任何数量的深度都是可能的,在示例中我们有深度 1、深度 2 和深度 3。
编辑
我创建了 foo.sh(一些不重要的幻想名称):
[
'Realtime' => [
'enabled' => [
'd' => [
'e' => 'f'
]
],
'a' => [
'b' => 'c'
]
]
'g' => [
'h' => 'i'
]
'Unrealtime' => 'abc'
]
工作一维命令:
sed -Ez ":a;s/.*Unrealtime' => +([^,]*).*/\1\n/" foo.sh | head -1
结果是
'abc'
工作二维命令:
sed -Ez ":a;s/.*g[^]]*h' => +([^,]*).*/\1\n/" foo.sh | head -1结果是
'一世'
三维命令:
sed -Ez ":a;s/.*Realtime*[^]]*a[^]]*b' => +([^,]*).*/\1\n/" foo.sh | head -1当且仅当
'a' => [ 'b' => 'c' ]是
Realtime的第一个孩子。所以,缺少了一些东西,因为我需要避免假设我搜索的元素是第一个孩子。工作四维命令:
sed -Ez ":a;s/.*Realtime[^]]*enabled[^]]*d[^]]*e' => +([^,]*).*/\1\n/" foo.sh | head -1同样,它仅在
enabled是Realtime的第一个孩子时才有效。我正在修改上面的测试用例,更改Realtime的子项的顺序。所以,似乎这个表达式中唯一缺少的东西是指定我们不一定要寻找第一个孩子的东西。
【问题讨论】:
-
用 bash 解析 PHP 数据似乎适得其反。为什么给你这个要求?
-
@glennjackman 这是违反直觉的,我不知道为什么客户想要这样。我有一个可行的解决方案,但我认为它不是很优雅。
-
查看最新更新...如果有人要求
e -> f,预期结果是什么?你返回子部分/数组 -[ 'g' => 'h' ]吗?你什么都不退吗?还有什么? -
旁白:你为什么使用
cat而不是file_get_contents($path)? -
@markp-fuso e -> f 是不合理的期望。在这种情况下,将要求 e -> f -> g。