How can I align the columns of tables in Bash?

前端 未结 9 2025
一个人的身影
一个人的身影 2020-12-02 08:25

I\'d like to output a table format text. What I tried to do was echo the elements of an array with \'\\t\', but it was misaligned.

My code

for((i=0;i         


        
9条回答
  •  半阙折子戏
    2020-12-02 09:02

    function printTable()
    {
        local -r delimiter="${1}"
        local -r data="$(removeEmptyLines "${2}")"
    
        if [[ "${delimiter}" != '' && "$(isEmptyString "${data}")" = 'false' ]]
        then
            local -r numberOfLines="$(wc -l <<< "${data}")"
    
            if [[ "${numberOfLines}" -gt '0' ]]
            then
                local table=''
                local i=1
    
                for ((i = 1; i <= "${numberOfLines}"; i = i + 1))
                do
                    local line=''
                    line="$(sed "${i}q;d" <<< "${data}")"
    
                    local numberOfColumns='0'
                    numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")"
    
                    # Add Line Delimiter
    
                    if [[ "${i}" -eq '1' ]]
                    then
                        table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
                    fi
    
                    # Add Header Or Body
    
                    table="${table}\n"
    
                    local j=1
    
                    for ((j = 1; j <= "${numberOfColumns}"; j = j + 1))
                    do
                        table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")"
                    done
    
                    table="${table}#|\n"
    
                    # Add Line Delimiter
    
                    if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]]
                    then
                        table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
                    fi
                done
    
                if [[ "$(isEmptyString "${table}")" = 'false' ]]
                then
                    echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1'
                fi
            fi
        fi
    }
    
    function removeEmptyLines()
    {
        local -r content="${1}"
    
        echo -e "${content}" | sed '/^\s*$/d'
    }
    
    function repeatString()
    {
        local -r string="${1}"
        local -r numberToRepeat="${2}"
    
        if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
        then
            local -r result="$(printf "%${numberToRepeat}s")"
            echo -e "${result// /${string}}"
        fi
    }
    
    function isEmptyString()
    {
        local -r string="${1}"
    
        if [[ "$(trimString "${string}")" = '' ]]
        then
            echo 'true' && return 0
        fi
    
        echo 'false' && return 1
    }
    
    function trimString()
    {
        local -r string="${1}"
    
        sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,'
    }
    

    SAMPLE RUNS

    $ cat data-1.txt
    HEADER 1,HEADER 2,HEADER 3
    
    $ printTable ',' "$(cat data-1.txt)"
    +-----------+-----------+-----------+
    | HEADER 1  | HEADER 2  | HEADER 3  |
    +-----------+-----------+-----------+
    
    $ cat data-2.txt
    HEADER 1,HEADER 2,HEADER 3
    data 1,data 2,data 3
    
    $ printTable ',' "$(cat data-2.txt)"
    +-----------+-----------+-----------+
    | HEADER 1  | HEADER 2  | HEADER 3  |
    +-----------+-----------+-----------+
    | data 1    | data 2    | data 3    |
    +-----------+-----------+-----------+
    
    $ cat data-3.txt
    HEADER 1,HEADER 2,HEADER 3
    data 1,data 2,data 3
    data 4,data 5,data 6
    
    $ printTable ',' "$(cat data-3.txt)"
    +-----------+-----------+-----------+
    | HEADER 1  | HEADER 2  | HEADER 3  |
    +-----------+-----------+-----------+
    | data 1    | data 2    | data 3    |
    | data 4    | data 5    | data 6    |
    +-----------+-----------+-----------+
    
    $ cat data-4.txt
    HEADER
    data
    
    $ printTable ',' "$(cat data-4.txt)"
    +---------+
    | HEADER  |
    +---------+
    | data    |
    +---------+
    
    $ cat data-5.txt
    HEADER
    
    data 1
    
    data 2
    
    $ printTable ',' "$(cat data-5.txt)"
    +---------+
    | HEADER  |
    +---------+
    | data 1  |
    | data 2  |
    +---------+
    

    REF LIB at: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash

提交回复
热议问题