쉘 스크립트를 사용하여 데이터 출력을 분할하고 형식을 지정하는 방법은 무엇입니까?

쉘 스크립트를 사용하여 데이터 출력을 분할하고 형식을 지정하는 방법은 무엇입니까?

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 테이블 코드로 변환하고 개별적으로 파일로 출력해야 하는 여러 소프트웨어의 기록 버전을 기록합니다.

예를 들어, , 및 를 동일한 파일로 출력하고 soft1( soft1_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

관련 정보