2009-11-05 50 views
24

我想用SED读取属性文件的文件,但不知道是否有一个更聪明的方式做到这一点从bash脚本?阅读的java的.properties从庆典

+0

这是一个奇妙的问题:)在这个特定的我想看看是否有一个简单的方法,我错过了(不知道\太愚蠢的想到等) – 2009-11-09 16:14:33

+0

尝试使用Gradle建立和部署,而不是BASH – dart 2014-09-15 09:10:50

回答

14

上述解决方案将用于基础。我不认为他们涵盖多行值。这里是一个awk程序,它将从标准输入解析Java的性能和生产shell环境变量到stdout:

BEGIN { 
    FS="="; 
    print "# BEGIN"; 
    n=""; 
    v=""; 
    c=0; # Not a line continuation. 
} 
/^\#/ { # The line is a comment. Breaks line continuation. 
    c=0; 
    next; 
} 
/\\$/ && (c==0) && (NF>=2) { # Name value pair with a line continuation... 
    e=index($0,"="); 
    n=substr($0,1,e-1); 
    v=substr($0,e+1,length($0) - e - 1); # Trim off the backslash. 
    c=1;         # Line continuation mode. 
    next; 
} 
/^[^\\]+\\$/ && (c==1) { # Line continuation. Accumulate the value. 
    v= "" v substr($0,1,length($0)-1); 
    next; 
} 
((c==1) || (NF>=2)) && !/^[^\\]+\\$/ { # End of line continuation, or a single line name/value pair 
    if (c==0) { # Single line name/value pair 
     e=index($0,"="); 
     n=substr($0,1,e-1); 
     v=substr($0,e+1,length($0) - e); 
    } else { # Line continuation mode - last line of the value. 
     c=0; # Turn off line continuation mode. 
     v= "" v $0; 
    } 
    # Make sure the name is a legal shell variable name 
    gsub(/[^A-Za-z0-9_]/,"_",n); 
    # Remove newlines from the value. 
    gsub(/[\n\r]/,"",v); 
    print n "=\"" v "\""; 
    n = ""; 
    v = ""; 
} 
END { 
    print "# END"; 
} 

正如你所看到的,多行值使事情更加复杂。要查看属性的值壳,只是在输出源:“”

cat myproperties.properties | awk -f readproperties.awk > temp.sh 
source temp.sh 

的变量将在地方有“_”,所以物业some.property将外壳是some_property。

如果你有ANT属性文件有属性插值(例如'$ {foo.bar}'),那么我建议在AntBuilder中使用Groovy。

这里是my wiki page on this very topic

+0

当多行值是最后定义并以空行结束时,我已更正了脚本的错误 – Toote 2016-07-28 14:33:39

1

在Perl:

while(<STDIN>) { 
    ($prop,$val)=split(/[=: ]/, $_, 2); 
    # and do stuff for each prop/val 
} 

没有测试过,应该是更加宽容的前/后间隔,评论等,但你的想法。无论是使用Perl(或其他语言)而不是sed,实际上都取决于您将属性解析为文件之外的属性。

请注意(如注释中突出显示的)Java属性文件可以有multiple forms of delimiters(尽管除了冒号之外,我还没有看到任何实践中使用过的东西)。因此,分割使用一个字符选择分裂。

最终,您可能更适合在Perl中使用Config::Properties模块,该模块用于解决此特定问题。

+0

这不一定工作。属性文件的键和值可以用空格,=字符或:字符(可能还有其他方式)分隔。我相信你也可以在单个属性文件中混合使用你使用的分隔符。 – 2009-11-07 19:09:22

+0

@托马斯 - 注意。虽然在实践中我不记得除了使用冒号以外的任何其他内容。 – 2009-11-07 23:08:17

0

我有一些shell scripts需要查找一些的.properties,并利用它们作为参数传递给没写程序。脚本的心脏是这样一行:

dbUrlFile=$(grep database.url.file etc/zocalo.conf | sed -e "s/.*: //" -e "s/#.*//") 

实际上,这是为重点grep和冒号之前和任何哈希后筛选出的东西。

1

如果你想用sed来解析-any-属性文件,你可能最终得到一个相当复杂的解决方案,因为该格式允许换行,不带引号的字符串,unicode的,等:http://en.wikipedia.org/wiki/.properties

一种可能解决方法是使用java本身将.properties文件预处理为bash友好的,然后将其源代码。例如: -

属性文件:

line_a : "ABC" 
line_b = Line\ 
     With\ 
     Breaks! 
line_c = I'm unquoted :(

就会变成:

line_a="ABC" 
line_b=`echo -e "Line\nWith\nBreaks!"` 
line_c="I'm unquoted :(" 

当然,这会产生性能差,但实现起来更简单/更清晰。

+1

'line_b = $'Line \ nWith \ nBreaks!' – 2009-11-05 19:02:18

+0

Dennis,它无法正常工作:http://pastebin.com/m503047e8。我错过了什么吗? – PaoloVictor 2009-11-05 19:13:18

4

一种选择是写一个简单的Java程序来为你做它 - 然后运行脚本中的Java程序。如果您只是从单个属性文件中读取属性,那看起来可能很愚蠢。但是,当您尝试从属性文件支持的某个配置值(例如Commons配置CompositeConfiguration)中获取配置值时,它变得非常有用。有一段时间,我们沿着shell脚本实现我们所需的路线,以获得与CompositeConfiguration相同的行为。然后我们明智地实现了,我们应该让CompositeConfiguration为我们做好工作!我不认为这是一个受欢迎的答案,但希望你觉得它有用。

如果你想用“壳”,最好的工具来分析文件,并有适当的编程控制(G)的awk
0

我有时只是来源属性文件到bash脚本。这将导致在脚本中使用文件中的名称和内容设置环境变量。也许这对你来说已经足够了。如果你必须做一些“真正的”解析,当然这不是要走的路。

0

嗯,我今天遇到同样的问题。这是穷人的解决方案,固然比聪明更简单;)

decl=`ruby -ne 'puts chomp.sub(/=(.*)/,%q{="\1";}).gsub(".","_")' my.properties` 
eval $decl 

然后,属性“my.java.prop”可以为$ my_java_prop进行访问。

这可以用sed或其他方式完成,但我终于用红宝石代替它的'irb',这对于实验来说非常方便。 这是非常有限的(点应该被'='替换,没有评论处理),但可能是一个起点。

@丹尼尔,我试图找出它,但Bash不喜欢变量名称中的点。

8

我写了一个脚本来解决这个问题,并把它放在我的github上。

properties-parser

+1

太棒了!将脚本复制到我的项目中,并很好地读入属性。 – Will 2012-08-21 21:02:35

0

我曾与

PROPERTIES_FILE=project.properties 
function source_property { 
    local name=$1 
    eval "$name=\"$(sed -n '/^'"$name"'=/,/^[A-Z]\+_*[A-Z]*=/p' $PROPERTIES_FILE|sed -e 's/^'"$name"'=//g' -e 's/"/\\"/g'|head -n -1)\"" 
} 

    source_property 'SOME_PROPERTY' 
24

了一定的成功,这可能是最简单的方法:grep的+切

# Usage: get_property FILE KEY 
function get_property 
{ 
    grep "^$2=" "$1" | cut -d'=' -f2 
} 
+0

这就是我最喜欢的简单情况。但是我会用'grep“^ $ PROP_KEY =”'(包括^和=分隔符)修改,因为属性键通常是其他键的前缀或后缀。 – Deleplace 2014-12-11 10:47:05

+3

这将在任何包含等号的属性上失败。一个更好的(更完整,更短,甚至更快)的解决方案将是'sed'/^$ 2 = /!d; s ///“”$ 1“'它具有与上面的'grep'相同的逻辑,但是也删除了匹配的部分,只留下要打印的参数值 – 2016-03-16 16:54:32

+0

属性允许属性名称和等号之间有空格。在grep或sed中使用正则表达式'^ $ 2 * ='允许使用空格 – ataylor 2016-03-28 19:05:44