awk ステートメントは char 変数の数を出力し、機能しません。

awk ステートメントは char 変数の数を出力し、機能しません。

csvファイルの最長行に基づいて点線を印刷するには、次のようにします。

awk -F ',' '
    BEGIN {
       longest_line=0
        for (i = 1; i <= NF; i++) {
           longest[i] = ""
        }
    }
    {
       for (i = 1; i <= NF; i++) {
           if (length($i) > length(longest[i])) {
               longest[i] = $i
           }
       }
    }
    
    END {
        for (i=1; i<=NF;i++) {
            longest_line += length(longest[i])
        }
        printf("%*s", longest_line, "=")
    }
'

完全なスクリプトは次のとおりです。

awk -F ',' -v smso="$smso" -v rmso="$rmso" 'BEGIN {
    count=1
    firstcol=0
    arraylen=1
    longest_line=0
   for (i = 1; i <= NF; i++) {
       longest[i] = ""
    }
}

{
    for (i=1;i<=NF;i++) {
            if (i==NF) {
                data[arraylen++]=$i
                data[arraylen++]="\n"
            } else {
                data[arraylen++]=$i
            }
    }
}


{
   for (i = 1; i <= NF; i++) {
       if (length($i) > length(longest[i])) {
           longest[i] = $i
       }
   }
}

END {
    for (i=1; i<=NF;i++) {
        longest_line += length(longest[i])
    }
    printf("%*s", longest_line, "b")
    for (i = 1; i <= length(data); i++) {
        if (data[i]=="\n") {
            firstcol++
           count=1  
            printf("%s", data[i])
        } else if (count==1 && i != 1) {
            printf("%s%s%s", "|", data[i], "|")
            count++
        } else {
            smso=$(tput smso)
            rmso=$(tput rmso)
            num_spaces=(length(longest[count])-length(data[i]))+1
            printf("%s%*s%s%s", (i==1?"|":""), (i==1?num_spaces-1:num_spaces), " ", firstcol==0?toupper(data[i]):data[i], "|")
            count++
        }
    }   
}'

入力ファイルは次のとおりです。

NUMBER,FNAME,LNAME,PHONE-TYPE:GROUPS
222-222-2222,Elizabeth,Taylor,office:beauty:
111-111-1111,Matt,Alex,personal:superhuman:cool:amazing:extra

希望の出力は次のとおりです。

==============================================================
|      NUMBER|     FNAME|  LNAME|           PHONE-TYPE:GROUPS|
|222-222-2222| Elizabeth| Taylor|              office:beauty:|
|111-111-1111|      Matt|   Alex| personal:cool:amazing:extra|

しかし、私の結果は次のとおりです。

                                                             =
|      NUMBER|     FNAME|  LNAME|           PHONE-TYPE:GROUPS|
|222-222-2222| Elizabeth| Taylor|              office:beauty:|
|111-111-1111|      Matt|   Alex| personal:cool:amazing:extra|

ベストアンサー1

sprintf("%*s", n, string)文字列を長さに合わせて左に塗りつぶします(実装に応じてバイト数または文字数 awk)。n スペースがあります

文字列をn回繰り返すには、ヘルパー関数を作成します。

function repeat(n, string,  result) {
  while (n-- > 0) result = result string
  return result
}

ここではmlrすぐにこのタスク(または同様のタスク)を実行し、CSVを正しく処理するために次のことをお勧めします。

$mlr --c2p --barred 猫ファイル.csv
+------------+---+---------+--------- ------- ------ ---------+
|数字       |名前     |名前  |通貨タイプ:グループ                      |
+------------+---+---------+--------- ------- ------ ---------+
| 222-222-2222 |エリザベステイラー|
111-111-1111 |マット|個人:スーパーマン:アメージング:エクストラ|
+------------+---+---------+--------- ------- ------ ---------+

または右揃えフィールドの場合:

$mlr --c2p --barred --right 猫ファイル.csv
+------------+---+---------+--------- ------- ------ ---------+
|       数字|     名前|  名前|                      通貨タイプ:グループ|
+------------+---+---------+--------- ------- ------ ---------+
| 222-222-2222 |エリザベステイラー|
111-111-1111 |マット|個人:スーパーマン:アメージング:エクストラ|
+------------+---+---------+--------- ------- ------ ---------+

mlr使用できない場合は、置き換えられた内容を代わりにawk使用します。perlawk

perl -MList::Util=zip -MTerm::ANSIColor -F, -lane '
  push @rows, [@F];
  $i = 0; for (@F) {
    $max[$i] = length if length > $max[$i];
    $i++;
  }
  
  END {
    $line = join("+", "", (map {"-" x ($_ + 2)} @max), "");
    print $line;
    print join("|", "", (map {colored(sprintf(" %*s ", @$_), "bold blue")} zip(\@max, shift @rows)), "");
    print $line;
    for (@rows) {
      print join("|", "", (map {sprintf " %*s ", @$_} zip(\@max, $_)), "");
    }
    print $line;
  }' file.csv

これは作る:

+--------------+-----------+--------+----------------------------------------+
|       NUMBER |     FNAME |  LNAME |                      PHONE-TYPE:GROUPS |
+--------------+-----------+--------+----------------------------------------+
| 222-222-2222 | Elizabeth | Taylor |                         office:beauty: |
| 111-111-1111 |      Matt |   Alex | personal:superhuman:cool:amazing:extra |
+--------------+-----------+--------+----------------------------------------+

タイトルは太い青です。

では、反復演算子を使用してperl文字列反復を実行します。結果はです。詳細より。x"string" x 3stringstringstringperldoc perlop

perlPerlモジュールは35年間使用されているため、ホイールを再構築する必要はほとんどありませんが、Perlモジュールはほとんどあらゆる用途に使用できます。私たちはすでに使用していますList::Util便利なリスト操作機能を備えたモジュールとTerm::ANSIColor上記のカラーテキストを出力しますが、Text::CSVCSVとText::ASCIITableテーブル形式を指定します。

$ perl -MText::CSV=csv -MText::ASCIITable -e '
  $c = csv(in => shift);
  $t = Text::ASCIITable->new;
  $t->setCols(shift @$c);
  $t->addRow($_) for @$c;
  print $t' file.csv
.----------------------------------------------------------------------------.
| NUMBER       | FNAME     | LNAME  | PHONE-TYPE:GROUPS                      |
+--------------+-----------+--------+----------------------------------------+
| 222-222-2222 | Elizabeth | Taylor | office:beauty:                         |
| 111-111-1111 | Matt      | Alex   | personal:superhuman:cool:amazing:extra |
'--------------+-----------+--------+----------------------------------------'

おすすめ記事