awkを使用して列(NF)と行番号(NR)を含む素晴らしいテーブル形式を印刷するにはどうすればよいですか?

awkを使用して列(NF)と行番号(NR)を含む素晴らしいテーブル形式を印刷するにはどうすればよいですか?

サンプル

wolf@linux:~$ awk {print} file.txt 
a b
b c
c d
wolf@linux:~$ 

データが非常に小さいので、これは簡単です。

wolf@linux:~$ awk 'BEGIN {print "  " 1 " " 2} {print NR,$0}' file.txt
  1 2
1 a b
2 b c
3 c d
wolf@linux:~$ 

より大きなデータのための同様の解決策はありますか?ヘッダーを手動で印刷するのではなく、部分的にfor loop同じものを使用するつもりです。BEGIN {print " " 1 " " 2}

答え1

このBEGIN部分は入力ファイルが開かれる前に実行されるため、for loop入力の最初の行をまだ読み取っていないため、Thereを実行しても役に立たないため、繰り返すフィールドの数がわかりません。 1つを追加しない限り、getline全く異なるウォーム缶です(参照http://awk.freeshell.org/AllAboutGetline)。

awkフィールドコンテンツを作成し、スペースを使用してフォーマットしますcolumn。たとえば、次のようになります。

$ awk '
    NR==1 { for (i=1; i<=NF; i++) printf " %s", i; print "" }
    { print NR, $0 }
' file  | column -s' ' -t
   1  2
1  a  b
2  b  c
3  c  d

入力ファイルにフィールド間に複数のスペースまたはタブがある場合は、awkスクリプトの最後の行{ print{ $1=$1; print

答え2

tbl必要なスキーマに基づいてテーブルを生成する groff コードを生成する groff ラッパーを使用してテーブルを生成できます。

ここでは、データに基づいてawkユーティリティを使用してgroff組版ユーティリティのコードを生成するtblユーティリティのコードを動的に生成します。

< file \
awk '
  BEGIN {
    OFS = "@"
    print ".TS"
    print "box,tab(", ");"
  }

  !NF {next}

  NR==1 {
    fx(" ", "c", "c", ".")
    fx(OFS) 
  }

  { $1 = NR OFS $1 };1

  END { print ".TE" }

  function fp(str, sep) {
    printf "%s%s", sep, str
  }

  function fx(sep, a, b, c,   i) {
    fp(a)
    for (i=1; i<=NF; i++)
      fp(b""?b:i, sep)
    fp("\n", c)
  }
' - | tbl - | groff -Tascii | grep .

出力:

+----------+
|    1   2 |
|1   A   B |
|2   B   C |
|3   C   D |
+----------+

答え3

forループを使用してフィールドを繰り返すことができます。 NR は現在の行番号、NF はその特定の行のフィールド数です。

{   printf ("%4d", NR);
    for (f = 1; f <= NF; ++f) printf (" %-6s", $f);
    printf ("\n");
}

ヘッダーの場合は、最初の行に表示する列数が見つかるまで待つ必要があります。だからこれ今後前のコード。フィールドの内容を表す$ fではなく、f自体をラベルとして印刷します。

NR == 1 {   printf ("%4d", NR);
    for (f = 1; f <= NF; ++f) printf (" %-6s", f);
    printf ("\n");
}

ソートを維持するには、最大フィールド幅を見つける必要があります。各 %-6 は、「左揃えで最大 6 文字のスペースで埋められる文字列フィールド」を意味します。

編集:高度なバージョンでは、すべてのデータを[NR、NF]でインデックス付けされた2D配列に保存し、ENDブロックとして出力できます。その後、2つのことをさらに実行できます。

(1)各列のセルの最大幅を見つけ、列の実際の幅を使用して%-10s形式を変更します。

(2)各列のすべてが数値の場合は、対応する%sを変更して値を右揃えにします。

関連情報