如何在bash中创建多列html表?

时间:2016-03-10 03:17:54

标签: html bash awk html-table

这可能比标题所暗示的要复杂一些。我基本上想要遍历一系列玩家名称(这将是表头),然后在两列中列出与其下每个玩家相关联的团队。

我成功使用awk使用以下代码创建单个列表:

for ((i=0; i<${#PLAYERS[@]}; ++i)); do
    awk -F '\n' -v NAME="${PLAYERS[i]}" 'BEGIN {print "<tr>"; print "  <th colspan="2">" NAME "</th>"; print "</tr>"} \
    {print "<tr>"; for (j=1; j<=NF; j++) print "  <td>"$j"</td>"; print "</tr>"}' \
    < ${PLAYERS[i]}teams.list
done

其中包括:

<tr>
  <th colspan=2>Player 1</th>
</tr>
<tr>
  <td>Team 1</td>
</tr>
<tr>
  <td>Team 2</td>
</tr>
<tr>
  <td>Team 3</td>
</tr>
<tr>
  <td>Team 4</td>
</tr>

(HTML的其余部分在别处生成,并且不相关。)

我想要的是:

<tr>
  <th colspan=2>Player 1</th>
</tr>
<tr>
  <td>Team 1</td>
  <td>Team 2</td>
</tr>
<tr>
  <td>Team 3</td>
  <td>Team 4</td>
</tr>

2 个答案:

答案 0 :(得分:1)

尽管可以修改现有代码来完成此任务,但我选择使用比awk更熟悉的方法重构它。

我使用的方法的一个附加功能是为具有奇数队伍的玩家自动添加一个空单元格。

首先,从您的示例中,我假设您将拥有一个名为“Player 1teams.list”的文件,其中包含以下文字:

Team 1
Team 2
Team 3
Team 4

以下是我提出的解决方案,针对可读性进行了评论和优化:

#!/bin/bash

# Array of players
PLAYERS=("Player 1")

# Loop through players array
for PLAYER in "${PLAYERS[@]}"; do

    # Echo the table header row for the current player
    echo "<tr>"
    echo "  <th colspan=2>${PLAYER}</th>"
    echo "</tr>"

    # Reset the TEAMS array on each loop (reuse the array for each player)
    TEAMS=()

    # Read each line of the teams file for the current player
    while IFS= read -r LINE || [[ -n "$LINE" ]]; do
        # Store the current player's teams in an array
        TEAMS+=("$LINE")
    done < "${PLAYER}teams.list"

    # Calculate the array key for the last line of the file
    # (array keys are used for line numbers, so they start at 0 instead of 1)
    LASTLINE="$(( ${#TEAMS[@]} - 1 ))"

    # Loop through teams for the current player
    for LINE in "${!TEAMS[@]}"; do

        # If the current line number is even, we are starting a table row
        if [ "$(( LINE % 2 ))" -eq 0 ]; then
            echo "<tr>"
            echo "  <td>${TEAMS[$LINE]}</td>"

            # If an even line is the last line of the file, add a blank cell
            if [ "$LINE" == "$LASTLINE" ]; then
                echo "  <td></td>"
                echo "</tr>"
            fi

        # If the current line number is odd, we are ending a table row
        else
            echo "  <td>${TEAMS[$LINE]}</td>"
            echo "</tr>"
        fi
    done
done

以下是上述代码的精简版本:

#!/bin/bash

# Array of players
PLAYERS=("Player 1")

for PLAYER in "${PLAYERS[@]}"; do
    echo -e "<tr>\n  <th colspan=2>${PLAYER}</th>\n</tr>"
    TEAMS=(); while IFS= read -r LINE || [[ -n "$LINE" ]]; do TEAMS+=("$LINE"); done < "${PLAYER}teams.list"
    LASTLINE="$(( ${#TEAMS[@]} - 1 ))"
    for LINE in "${!TEAMS[@]}"; do
        if [ "$(( LINE % 2 ))" -eq 0 ]; then
            echo -e "<tr>\n  <td>${TEAMS[$LINE]}</td>"
            if [ "$LINE" == "$LASTLINE" ]; then echo -e "  <td></td>\n</tr>"; fi
        else
            echo -e "  <td>${TEAMS[$LINE]}</td>\n</tr>"
        fi
    done
done

修改:我已使用您提供的awk代码发布了新答案

答案 1 :(得分:0)

您可以使用if语句来检查偶数/奇数行:

for ((i=0; i<${#PLAYERS[@]}; ++i)); do
    awk -F '\n' -v NAME="${PLAYERS[i]}" 'BEGIN {print "<tr>\n  <th colspan="2">" NAME "</th>\n</tr>"} \
    {if (NR%2==1) {print "<tr>\n  <td>"$0"</td>"} else {print "  <td>"$0"</td>\n</tr>"}}
    END {if (NR%2==1) {print "</tr>"}}' \
    "${PLAYERS[i]}teams.list"
done

if语句使用公式NR%2==1(行号modulo 2等于1)检查当前行是否为奇数,然后为该表行打印相应的html。

我还进行了以下代码更改:

  • 删除了for循环,因为awk已遍历文件的每一行
  • 删除&#34;&lt;&#34;文件重定向,因为awk已经期望文件名作为最后一个参数
  • 使用print换行符
  • 加入了多个\n语句

注意:我将此作为单独的答案发布,因为我在原始帖子中完全重写了您的代码。