2012-10-07 4 views
28

テーブル形式のテキストを出力したいと思います。私がしようとしたのは配列の要素を '\ t'でエコーしていたのですが、位置がずれることがありました。 私のコードバッシュ出力テーブル

for((i=0;i<array_size;i++)); 
do 
    echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i] 
done; 

マイ出力

a very long string..........  112232432  anotherfield 
a smaller string   123124343  anotherfield 

所望の出力

a very long string..........  112232432  anotherfield 
a smaller string     123124343  anotherfield 

答えて

39

printfは、多くの人々が存在することを忘れ素晴らしい小さなプログラムです。それはかなり強力です。

$ for num in 1 10 100 1000 10000 100000 1000000; do printf "%10s %s\n" $num "foobar"; done 
     1 foobar 
     10 foobar 
     100 foobar 
     1000 foobar 
    10000 foobar 
    100000 foobar 
    1000000 foobar 

$ for((i=0;i<array_size;i++)); 
do 
    printf "%10s %10d %10s" stringarray[$i] numberarray[$i] anotherfieldarray[%i] 
done 

私は文字列に%10sを使用に注意してください。 %sは重要な部分です。文字列を使用するように指示します。中央の10には、いくつの列があるかが記載されています。 %dは数字(数字)です。

man 1 printf詳細については、

+14

テーブルを印刷するときに便利なのは1つのアドバイスだけです: '%-10s' wiil長さ10の左揃えの文字列を生成する – steffen

74

使用カラムコマンド:

column -t -s' ' filename 
+0

'printf'も有用です。 – Mat

+2

このような彼のニーズに合っていません。 –

+0

@putnickこれは彼のニーズにちょうど適合します。それが不要な '\ t'を行う理由は、単語間に固定長のスペースを与える表のコラムを自分自身で行うことです。彼がする必要があるのは、出力を 'column'にパイプすることだけです。 –

5

あなたが必要とまったく同じ出力を持っている、あなたはフォーマットする必要があるそのようなファイル:

a very long string..........\t  112232432\t  anotherfield\n 
a smaller string\t  123124343\t  anotherfield\n 

そして使用:

$ column -t -s $'\t' FILE 
a very long string.......... 112232432 anotherfield 
a smaller string    123124343 anotherfield 
+0

' $ '\ t''の '$'とは何ですか? – rjmunro

+0

これはbash構文のタブです。http://mywiki.wooledge.org/Quotes –

+0

2つの列のサイズが5文字を超える場合、タブストップの使用は完全に使用できなくなります。 – UtahJarhead

3

あなたがこれを実行していた場所はわかりませんが、あなたが投稿したコードは、私がよく知っているbashにはない、あなたが与えた出力を生成しません。あなたはファイルからこれらの配列を取得している場合、彼らはタブが含まれている場合がありますので、私は、inteadタブのグループセパレーター文字(1D)を使用してい

stringarray=('test' 'some thing' 'very long long long string' 'blah') 
numberarray=(1 22 7777 8888888888) 
anotherfieldarray=('other' 'mixed' 456 'data') 
array_size=4 

for((i=0;i<array_size;i++)) 
do 
    echo ${stringarray[$i]} $'\x1d' ${numberarray[$i]} $'\x1d' ${anotherfieldarray[$i]} 
done | column -t -s$'\x1d' 

注:

は、この代わりにしてみてください。

1

あなたが不思議に思っているよりも簡単です。

あなたもセミコロンファイルとヘッダによって分離で作業している場合:(セパレータとしてタブを使用して)アレイを使用している場合

$ (head -n1 file.csv && sort file.csv | grep -v <header>) | column -s";" -t 

for((i=0;i<array_size;i++)); 
do 

    echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i] >> tmp_file.csv 

done; 

cat file.csv | column -t 
0
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を実行

$ 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 | 
+---------+ 

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