Чтение Java-файла .properties из Bash

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
27
задан skaffman 4 January 2012 в 23:35
поделиться

8 ответов

Вышеупомянутые решения подойдут для основ. Однако я не думаю, что они охватывают многострочные значения. Вот программа awk, которая будет разбирать свойства Java из stdin и выдавать переменные окружения 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";
}

Как вы можете видеть, многострочные значения усложняют ситуацию. Чтобы увидеть значения свойств в shell, просто укажите источник в выводе:

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

Переменные будут иметь '_' вместо '.', поэтому свойство some.property будет some_property в shell.

Если у вас есть файлы свойств ANT с интерполяцией свойств (например, '${foo.bar}'), то я рекомендую использовать Groovy с AntBuilder.

Вот моя вики-страница на эту тему.

16
ответ дан 28 November 2019 в 04:50
поделиться

One option is to write a simple Java program to do it for you - then run the Java program in your script. That might seem silly if you're just reading properties from a single properties file. However, it becomes very useful when you're trying to get a configuration value from something like a Commons Configuration CompositeConfiguration backed by properties files. For a time, we went the route of implementing what we needed in our shell scripts to get the same behavior we were getting from CompositeConfiguration. Then we wisened up and realized we should just let CompositeConfiguration do the work for us! I don't expect this to be a popular answer, but hopefully you find it useful.

4
ответ дан 28 November 2019 в 04:50
поделиться

Если вы хотите использовать sed для синтаксического анализа файла -any- .properties, вы можете столкнуться с довольно сложным решением, поскольку формат допускает разрывы строк, строки без кавычек, юникод и т. Д .: http://en.wikipedia.org/wiki/.properties

Одним из возможных обходных путей было бы использование самой java для предварительной обработки файла .properties во что-то удобное для bash, а затем его источник. Например:

.properties файл:

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
ответ дан 28 November 2019 в 04:50
поделиться

У меня есть несколько сценариев оболочки , которым нужно найти некоторые .properties и использовать их в качестве аргументов для программ, которые я не делал » я пишу. В основе сценария лежит такая строка:

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

Фактически, это grep для ключа и отфильтровывает все, что находится перед двоеточием и после любого хэша.

0
ответ дан 28 November 2019 в 04:50
поделиться

In Perl:

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

Not tested, and should be more tolerant of leading/trailing spaces, comments etc., but you get the idea. Whether you use Perl (or another language) over sed is really dependent upon what you want to do with the properties once you've parsed them out of the file.

Note that (as highlighted in the comments) Java properties files can have multiple forms of delimiters (although I've not seen anything used in practice other than colons). Hence the split uses a choice of characters to split upon.

Ultimately, you may be better off using the Config::Properties module in Perl, which is built to solve this specific problem.

1
ответ дан 28 November 2019 в 04:50
поделиться

Иногда я просто загружал файл свойств в сценарий bash. Это приведет к тому, что переменные среды будут установлены в сценарии с именами и содержимым из файла. Может быть, и вам этого хватит. Если вам нужно провести "настоящий" синтаксический анализ, это, конечно, не лучший вариант.

0
ответ дан 28 November 2019 в 04:50
поделиться

, если вы хотите использовать "оболочку", лучший инструмент для анализа файлов и надлежащего управления программированием - (g ) awk. Используйте sed только простую замену.

0
ответ дан 28 November 2019 в 04:50
поделиться

Хм, сегодня я столкнулся с той же проблемой. Это решение для бедняков, по общему признанию, более простое, чем умное;)

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

тогда свойство my.java.prop можно получить как $ my_java_prop.

Это можно сделать с помощью sed или чего-то еще, но в конце концов я пошел с рубином в качестве irb, удобного для экспериментов. Он довольно ограничен (точки следует заменять только перед знаком '=', без обработки комментариев), но может быть отправной точкой.

@Daniel, Я пытался найти его, но Bash не любил точки в именах переменных.

0
ответ дан 28 November 2019 в 04:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: