月番号を月名に変更し、同じ月の行に対して一度印刷します。

月番号を月名に変更し、同じ月の行に対して一度印刷します。

私はawkプログラミングの初心者です。次のように説明したいと思います。

私は持っています:

month D1 D2 D3
01    25 26 23
01    13 12 11
01    48 45 12
02    77 87 45
02    63 99 12

私が欲しい:

month D1 D2 D3
January 25 26 23
        13 12 11
        48 45 12
February 77 87 45
         63 99 12

答え1

zsh(ユーザーロケールの月名リストを取得する)+を使用してくださいawk。おそらく次のようになります。

zmodload zsh/langinfo
awk -v months=${(vj[:])langinfo[(I)MON_<1-12>]} '
  BEGIN{split(months, month, ":")}
  NR > 1 {
    this_month = month[0+$1]
    if (this_month == last)
      $1 = blanks
    else
      blanks = sprintf("%*s", length(last = $1 = this_month), "")
  }
  {print}' < your-file

月名に複数バイトでエンコードされた文字を含むロケール(たとえば、février2バイトでエンコードされたロケール)では、fr_FR.UTF-8マルチバイトをサポートしない実装ではソートがオフになるé可能性があります。awkmawk

たとえば、次のような結果が得られます。

month D1 D2 D3
janvier 25 26 23
        13 12 11
        48 45 12
février 77 87 45
        63 99 12

gawk、しかし

month D1 D2 D3
janvier 25 26 23
        13 12 11
        48 45 12
février 77 87 45
         63 99 12

そしてmawk

ユーザーのロケールに関係なく、月名を英語で表示したい場合に設定できますLC_ALL=C

答え2

また試み

awk '
NR == 1         {split($0, Month, ";")
                 next
                }
FNR > 1         {Tmp  = $1
                 $1   = Month[$1+0]
                 if (Tmp == Last) gsub(/./, " ", $1)
                 Last = Tmp
                }
1
' - file <<< $(LC_ALL=C locale mon)
month D1 D2 D3
January 25 26 23
        13 12 11
        48 45 12
February 77 87 45
         63 99 12

コマンドから月名を取得し、locale数値$1を名前に変換し、重複した名前に対応するスペースの数を入力します。

答え3

文書:months.awk

#! /usr/bin/awk -f

BEGIN {
    # Months array initialization
    months["01"] = "January"
    months["02"] = "February"
    months["03"] = "March"
    months["04"] = "April"
    months["05"] = "May"
    months["06"] = "June"
    months["07"] = "July"
    months["08"] = "August"
    months["09"] = "September"
    months["10"] = "October"
    months["11"] = "November"
    months["12"] = "December"
}
{
    # key is the month number
    k = $1
}
! (k in months) {
    # Month not found: print line as is
    print
    # Next line!
    next
}
! (k in tabs) {
    # month name read from array
    month_name = months[k]
    # month name length
    month_len = length(month_name)
    # remove month number into the line
    gsub(/^[0-9]+ +/, "")
    # print new line
    printf("%*.*s %s\n", month_len, month_len, month_name, $0)
    # store in tabs array the month length
    tabs[k] = month_len
    # Next line!
    next
}
{
    # remove month number into the line
    gsub(/^[0-9]+ +/, "")
    # print new line
    printf("%*.*s %s\n", tabs[k], tabs[k], "", $0)
}

と呼ばれる:

awk -f months.awk your_filename

またはすでに完了している場合chmod 755 months.awk

./months.awk your_filename

答え4

GNU awkを使用して時間関数を実装します。

$ awk '
    NR==1 { mth = $1 }
    NR>1  { mth = ($1==prev ? "" : strftime("%B",mktime("2020 " $1 " 15 12 0 0 0"))); prev=$1 }
    { $1 = sprintf("%-9s",mth); print }
' file
month     D1 D2 D3
January   25 26 23
          13 12 11
          48 45 12
February  77 87 45
          63 99 12

または awk を使用してください。

$ awk '
    BEGIN { split("January February March April May June July August September October November December",mths) }
    NR==1 { mth = $1 }
    NR>1  { mth = ($1==prev ? "" : mths[$1+0]); prev=$1 }
    { $1 = sprintf("%-9s",mth); print }
' file
month     D1 D2 D3
January   25 26 23
          13 12 11
          48 45 12
February  77 87 45
          63 99 12

関連情報