
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
使用します。perl
awk
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 3
stringstringstring
perldoc perlop
perl
Perlモジュールは35年間使用されているため、ホイールを再構築する必要はほとんどありませんが、Perlモジュールはほとんどあらゆる用途に使用できます。私たちはすでに使用していますList::Util
便利なリスト操作機能を備えたモジュールとTerm::ANSIColor
上記のカラーテキストを出力しますが、Text::CSV
CSVと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 |
'--------------+-----------+--------+----------------------------------------'
答え2
printf("%*s", longest_line, "=")
=
スペースでインデントされlongest_line-1
た文字を印刷します。あなたはこれが欲しい:
line = sprintf("%*s", longest_line, "")
gsub(/ /,"=",line)
print line
FWIW、これはawkを使って目的のタスクを実行するコードを書く方法です。
$ cat tst.awk
BEGIN { FS=","; OFS="|"; hdrChar="=" }
{
for (colNr=1; colNr<=NF; colNr++) {
val = $colNr
vals[NR,colNr] = val
wid = length(val)
wids[colNr] = (wid > wids[colNr] ? wid : wids[colNr])
}
}
END {
for ( colNr=1; colNr<=NF; colNr++ ) {
row = row hdrChar sprintf("%*s",wids[colNr],"")
}
gsub(/ /,hdrChar,row)
print row hdrChar
for ( rowNr=1; rowNr<=NR; rowNr++ ) {
row = ""
for ( colNr=1; colNr<=NF; colNr++ ) {
row = row OFS sprintf("%*s",wids[colNr],vals[rowNr,colNr])
}
print row OFS
}
}
$ awk -f tst.awk file
======================================================================
| NUMBER| FNAME| LNAME| PHONE-TYPE:GROUPS|
|222-222-2222|Elizabeth|Taylor| office:beauty:|
|111-111-1111| Matt| Alex|personal:superhuman:cool:amazing:extra|
val = $colNr
または、同様に変更して、val = " " $colNr " "
適切と思われるスペースでいくつかのフィールドを埋めます。