使用 BASH 脚本解析文件并将模式匹配复制到变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6177970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parse file with BASH script and copy pattern match to a variable
提问by Bryan
Say I have a file (php as it happens), with a number of variable declarations:
假设我有一个文件(碰巧是 php),其中包含许多变量声明:
$dbuser = 'fred';
$dppass = 'abc123';
$dhhost = '127.0.0.1';
What I want to do from a BASH script, is parse this file, identify the variables I need, and read their values into variables I can access from my BASH script.
我想从 BASH 脚本中做的是解析这个文件,识别我需要的变量,并将它们的值读入我可以从我的 BASH 脚本访问的变量中。
Obviously, the above file being PHP, has other lines that I'm not interested in.
显然,上面的文件是 PHP,还有我不感兴趣的其他行。
I can extract the info I need from the bash shell using the following command:
我可以使用以下命令从 bash shell 中提取我需要的信息:
grep $dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2
which neatly returns
整齐地返回
fred
But when I try to add this to a bash script to put the output into a variable using backticks, as follows:
但是,当我尝试将其添加到 bash 脚本以使用反引号将输出放入变量时,如下所示:
dbuser=`grep $dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2`
my BASH script hangs at this point.
我的 BASH 脚本此时挂起。
Why is this hanging, or, is there a better way of doing what I'm trying to achieve?
为什么会挂起,或者有没有更好的方法来做我想要实现的目标?
回答by Wil Moore III
Try it this way:
试试这个方法:
dbuser=$(grep $dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2)
The reason this works and the backticks did not is in the way $(command) handles quoting vs. how the old style backticks handles quoting.
这有效而反引号不起作用的原因在于 $(command) 处理引用的方式与旧样式反引号处理引用的方式。
In other words, the following backtick command would have worked just as well:
换句话说,以下反引号命令也能正常工作:
dbuser=`grep '$dbuser' config.php.inc | grep -Po "'.*'" | cut -d"'" -f 2`
- Used single quotes to enclose $dbuser since single quotes means use the literal text rather than interpolate it as a shell variable.
- Removed the escaping from .* since it is not needed.
- Removed the escaping from the cut command since it is not needed.
- 使用单引号将 $dbuser 括起来,因为单引号意味着使用文字文本而不是将其插入为 shell 变量。
- 从 .* 中删除了转义,因为它不需要。
- 从 cut 命令中删除了转义,因为它不需要。
BTW, this would have worked as well:
顺便说一句,这也可以:
dbuser=`grep '$dbuser' config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2`
Additionally, the $(command) syntax is in general the best approach whenever possible. Use `` only for portability reasons if you must support a platform that is absolutely known to not support $(command). This is IMHO very rare, so the rule of thumb is to lean towards $(command) from the start.
此外,只要可能,$(command) 语法通常是最好的方法。如果您必须支持绝对不支持 $(command) 的平台,请仅出于可移植性原因使用 ``。恕我直言,这是非常罕见的,所以经验法则是从一开始就倾向于 $(command) 。
回答by glenn Hymanman
This will return text like var='value';
这将返回类似的文本 var='value';
awk '
match(, /^$([[:alnum:]_]+)=?/, m){
gsub(/^[^=]+=[[:space:]]*/, "")
print m[1] "=" sed -e 's/$//' -e 's/ *= */=/' file.php
}
' < file.php
You can evalthe output.
你可以eval输出。
update
更新
This is a lot simpler than the above. I realized all you need to do is delete the first $and remove the spaces around the =:
这比上面的要简单得多。我意识到您需要做的就是删除第一个$并删除 周围的空格=:
eval $(sed -n "s/^$\([a-zA-Z][a-zA-Z0-9_]*\) *= *'\(.*\)' *;/='';/p")
echo User:$dbuser Pass:$dppass Host:$dhhost
回答by jm666
With some basic checking and safety
通过一些基本的检查和安全
User:fred Pass:abc123 Host:127.0.0.1
will print for your example
将为您的示例打印
dbuser=$(perl -ne "print $1 if /$dbuser.*'(.*)'/" config.php.inc)
回答by VGE
It sound like that there is a missing \
听起来好像缺少一个\
Check if this is not \\$dbuser
检查这是否不是 \\$dbuser
If you have access to perl try:
如果您有权访问 perl,请尝试:
##代码##Note :
-e use next parameter as a one liner script
-n use all parameter as file argument
print $1 print the matched pattern when matched
The parathesis in the regex define the $1 capture group.
注意: -e 使用下一个参数作为单行脚本
-n 使用所有参数作为文件参数
print $1 匹配时打印匹配的模式
正则表达式中的 parathesis 定义了 $1 捕获组。

