скрипт bash для перевода XML - PullRequest
1 голос
/ 14 января 2010

Привет, у меня есть десятки файлов XML с
Мне нужно это:

<p begin="00:06:28;12" end="00:00:02;26">

переведено на это:

<p begin="628.12" end="631.08">

Я знаю, что для этого нужен простой awk или sed, но я новичок; может кто-нибудь помочь

Ответы [ 4 ]

5 голосов
/ 14 января 2010

Таблица стилей XSL будет более надежной. Вы можете запустить его из сценария оболочки.

3 голосов
/ 15 января 2010

Ах, ghostdog74 избил меня до этого. Однако мой также имеет дело с MS.

awk '
    function timeToMin(str) {
        time_re = "([0-9][0-9]):([0-9][0-9]):([0-9][0-9]);([0-9][0-9])"

        # Grab all the times in seconds. 
        s_to_s =  gensub(time_re, "\\3", "g", str);
        m_to_s = (gensub(time_re, "\\2", "g", str)+0)*60;
        h_to_s = (gensub(time_re, "\\1", "g", str)+0)*60*60;
        ms     =  gensub(time_re, "\\4", "g", str);

        # Create float.
        time_str = (h_to_s+m_to_s+s_to_s)"."ms;

        # Converts from num to str.
        return time_str+0; 
    }
    function addMins(aS, bS) {
        # Split by decimal point
        split(aS, aP, ".");
        split(bS, bP, ".");

        # Add the seconds and ms.
        min = aP[1]+bP[1];
        ms  = aP[2]+bP[2];
        if (ms > 59) {
            ms = ms-60;
            mins++;
        }

        # Return addition.
        return (min"."ms)+0;
    }
    {
        re = "<p begin=\"(.+)\" end=\"(.+)\">";
        if ($0 ~ re) {
            # Pull out the data.
            strip_re = ".*"re".*";
            begin_str = gensub(strip_re, "\\1", "g");
            end_str   = gensub(strip_re, "\\2", "g");

            # Convert.
            begin = timeToMin(begin_str);
            end   = timeToMin(end_str);

            elapsed_end=addMins(begin, end);

            sub(re,"<p begin=\""begin"\" end=\""elapsed_end"\">");
        }

        print $0;
    }
' file
1 голос
/ 15 января 2010

вот кое-что для начала. Я не знаю, как вы хотите добавить десятичное значение, поэтому вы делаете это сами

awk '/.*<p[ ]+begin=.*[ ]+end=.*/{
    o=$0
    gsub(/.*begin=\042|\042|>/,"")
    m=split($0,s,"end=")
    gsub(/[:;]/," ",s[1])
    gsub(/[:;]/," ",s[2])
    b=split(s[1],begin," ")
    e=split(s[2],end," ")
    # do date maths here
    if (b>3){
        tbegin=(begin[1]*3600) + (begin[2]*60) + begin[3]  ##"."begin[4]
    }else{
        tbegin=(begin[1]*60) + begin[3]  ##"."begin[4]
    }
    # add the decimal yourself
    if(e>3) {
        tend = (end[1]*3600) +(end[2]*60)+end[3]+ tbegin ##"."end[4]
    }else{
        tend = (end[1]*60)+end[3]+ tbegin ##"."end[4]
    }
    string=gensub("(.*begin=\042).*( end=\042)(.*)\042>", "\\1" tbegin "\042\\2" tend"\042>","g",o)
    $0=string
}
{print}
' file

например

$ cat file
<p begin="00:06:28;12" end="00:00:02;26">
<p begin="00:08:45;12" end="00:00:23;26">
<p begin="08:45;12" end="00:2;26">

$ ./shell.sh
<p begin="388" end="390">
<p begin="525" end="548">
<p begin="492" end="518">

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

0 голосов
/ 15 января 2010

Я бы рекомендовал использовать Perl (или другой язык сценариев) с модулем синтаксического анализа XML (см. здесь для получения дополнительной информации о Perl и XML).

Таким образом, вы можете надежно анализировать XML и извлекать / манипулировать значениями в программной форме. Запишите слово надежно. В вашем XML могут использоваться кодировки символов, которые не будут соблюдаться простым sed / awk (маловероятно, что в этом сценарии это допустимо, но о таких проблемах стоит знать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...