将月份编号修改为月份名称,并为同一月份的行打印一次

将月份编号修改为月份名称,并为同一月份的行打印一次

我是 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évrier在按 2 个字节编码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

相关内容