シェルスクリプトを使用してデータ出力を分割してフォーマットする方法は?

シェルスクリプトを使用してデータ出力を分割してフォーマットする方法は?

YAMLファイルをHTMLテーブルに変換しようとしていますが、いくつかの複雑な条件が関係しています。私はシェルスクリプトを使ってこれを行うことができることを知っていますが、実装にはいくつかの問題があり、コミュニティに助けを求めました。 。

YAMLのコンテンツ形式は次のとおりです。

- soft1:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft1_beta_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft1_alpha_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2_beta_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2_alpha_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip

< Omit more... >

これは、HTMLテーブルコードに変換し、個別にファイルに出力する必要がある複数のソフトウェアの履歴バージョンを記録します。

たとえば、、、とを同じファイルに出力しsoft1soft1_beta_verファイルsoft1_alpha_ver名を使用soft1)、Soft2を別のファイルに出力します。

変換する必要があるHTMLテーブルの形式は次のとおりです。

<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>soft1</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
    </tbody>
</table>

これは私が試しているシェルスクリプトですが、出力を複数のファイルに分割する方法とソフトウェアタイプ変数を取得する方法がわかりません。

#!/usr/bin/env bash

cat  << EOF
<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>
EOF

while IFS=": " read -r softver softlink
do
cat << EOF
        <tr>
            <td>$softver</td>
            <td></td>
            <td><a href="$softlink">download</a></td>
        </tr>
EOF
done

cat << EOF
    </tbody>
</table>
EOF

これについての助言やアドバイスは非常に役に立ち、大変感謝します。

答え1

ソース入力ファイルから必要なHTMLを生成するだけです。

$ cat ../tst.awk
/^-/ {
    sub(/:$/,"")
    out = type = $NF
    sub(/_.*/,"",out)
    close(out)
    if ( !seen[out]++ ) {
        prtBeg()
    }
    next
}
{
    sub(/:$/,"",$1)
    prtElt("<tr>")
    prtElt("<td>" type "</td>")
    prtElt("<td>" $1 "</td>")
    prtElt("<td>" $2 "</td>")
    prtElt("</tr>")
}
END {
    for (out in seen) {
        prtEnd()
    }
}

function prtElt(str) {
    depth[out] += gsub("<[^/<>]+>","&",str)
    printf "%*s%s\n", (depth[out]-1)*4, "", str >> out
    depth[out] -= gsub("</[^<>]+>","&",str)
}

function prtBeg() {
    prtElt("<table>")
    prtElt("<thead>")
    prtElt("<tr>")
    prtElt("<th>type</th>")
    prtElt("<th>ver</th>")
    prtElt("<th>link</th>")
    prtElt("</tr>")
    prtElt("</thead>")
    prtElt("<tbody>")
}

function prtEnd() {
    prtElt("</tbody>")
    prtElt("</table>")
}

$ ls
$
$ awk -f ../tst.awk ../file
$
$ ls
soft1  soft2

$ cat soft1
<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>soft1</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
    </tbody>
</table>

$ cat soft2
<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>soft2</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft2</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft2</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft2_beta_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft2_beta_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft2_beta_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
        <tr>
            <td>soft2_alpha_ver</td>
            <td>V1.0.1</td>
            <td>http://example.com/v1.0.1.zip</td>
        </tr>
        <tr>
            <td>soft2_alpha_ver</td>
            <td>V1.0.2</td>
            <td>http://example.com/v1.0.2.zip</td>
        </tr>
        <tr>
            <td>soft2_alpha_ver</td>
            <td>V1.0.3</td>
            <td>http://example.com/v1.0.3.zip</td>
        </tr>
    </tbody>
</table>

上記はこの入力ファイルに対して実行されました。

$ cat ../file
- soft1:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft1_beta_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft1_alpha_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2_beta_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip
- soft2_alpha_ver:
    V1.0.1: http://example.com/v1.0.1.zip
    V1.0.2: http://example.com/v1.0.2.zip
    V1.0.3: http://example.com/v1.0.3.zip

答え2

次のように動作しますsed

解析.sed

1r header

/^-/ {
  s/- //
  s/://
  h
}

G
s/ *([^:]+): ([^\n]+)\n(.*)/        <tr>\n            <td>\3<\/td>\n            <td>\1<\/td>\n            <td><a href="\2">Download<\/a><\/td>\n        <\/tr>/p

$r footer

どこヘッダーそして歩行者含む:

ヘッダー

<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>

歩行者

    </tbody>
</table>

次のように実行します。

sed -Enf parse.sed infile

出力は3つの部分に分けられます。ファイルのインポート:

<table>
    <thead>
        <tr>
            <th>type</th>
            <th>ver</th>
            <th>link</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>soft1</td>
            <td>V1.0.1</td>
            <td><a href="http://example.com/v1.0.1.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.2</td>
            <td><a href="http://example.com/v1.0.2.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1</td>
            <td>V1.0.3</td>
            <td><a href="http://example.com/v1.0.3.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.1</td>
            <td><a href="http://example.com/v1.0.1.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.2</td>
            <td><a href="http://example.com/v1.0.2.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_beta_ver</td>
            <td>V1.0.3</td>
            <td><a href="http://example.com/v1.0.3.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.1</td>
            <td><a href="http://example.com/v1.0.1.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.2</td>
            <td><a href="http://example.com/v1.0.2.zip">Download</a></td>
        </tr>
        <tr>
            <td>soft1_alpha_ver</td>
            <td>V1.0.3</td>
            <td><a href="http://example.com/v1.0.3.zip">Download</a></td>
        </tr>
    </tbody>
</table>

答え3

たとえば、各行で3つの変数を「読み取り」行がヘッダーであるかどうかを区別する必要があります。

while IFS=": " read -r a b c
do
    if [[ "$a" == "-" ]]; then
        t=$b
    else
        cat << EOF
        <tr>
            <td>$t</td>
            <td>$a</td>
            <td><a href="$b:$c">download</a></td>
        </tr>
EOF
    fi
done

関連情報