如何将用月份名称表示的日期转换为数字月份名称?

如何将用月份名称表示的日期转换为数字月份名称?

date我使用 MacOS,并且格式有变量

3.Jan.2023,
12.Nov.2017,
9.Apr.2022,
...

我需要改变

03.01.2023,
12.11.2017,
09.04.2022,
...

答案1

苹果系统date允许您指定转换的输入和输出格式:

for inp in "3.Jan.2023" "12.Nov.2017" "9.Apr.2022"; do
    date -j -f "%d.%b.%Y" "$inp" "+%d.%m.%Y"
done

根据strptime():

  • %b月份,使用区域设置的月份名称;可以指定缩写或全名。
  • %d该月的第几天[01,31];允许使用前导零,但不是必需的。
  • %m月份号[01,12];允许使用前导零,但不是必需的。
  • %Y年份,包括世纪(例如,1988)。

输出:

03.01.2023
12.11.2017
09.04.2022

答案2

使用任何 awk:

$ awk '
    BEGIN { FS=OFS="," }
    {
        split($1,d,".")
        $1 = sprintf("%02d.%02d.%04d", d[1], index("  JanFebMarAprMayJunJulAugSepOctNovDec",d[2])/3, d[3])
        print
    }
' file
03.01.2023,
12.11.2017,
09.04.2022,

前面有2个空格Jan

答案3

您可以使用awk从一种格式转换为另一种格式:

awk -F. '
    BEGIN { m["Jan"]=1; m["Feb"]=2; m["Mar"]=3; m["Dec"]=12 }
    { printf "%02d.%02d.%04d,\n", $1, m[$2], $3 }
' file

BEGIN生产线需要完成以遵循所有月份的模式。

答案4

使用(以前称为 Perl_6)

~$ raku -pe 'my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \ 
             s/ <( (\d**1..2) \. (<alpha>**3) )> \. \d**4 \, /{sprintf q[%02d.%02d], $0, %months{$1}}/;'  file 

#OR

~$ raku -pe 'my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \ 
             s[ <( (\d**1..2) \. (<alpha>**3) )> \. \d**4 \, ] = "{sprintf q[%02d.%02d], $0, %months{$1}}";'  file

或者:

~$ raku -e 'my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \
            put S/ <( (\d**1..2) \. (<alpha>**3) )> \. \d**4 \, /{sprintf q[%02d.%02d], $0, %months{$1} }/ for lines();' file

#OR

~$ raku -e 'my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12; \
            put S[ <( (\d**1..2) \. (<alpha>**3) )> \. \d**4 \, ] = "{sprintf q[%02d.%02d], $0, %months{$1} }" for lines();'  file

简而言之,您可以使用 Raku 替换字符串月份并替换为数字(整数)。也可以格式化天数(使用sprintf)。声明一个%months以 3 个字母的月份名称作为键的哈希,并将数字分配1..12为值。归约[Z=>]元运算符从给定的两个列表中取出连续元素,并将它们配对为key => value。结果say %months.sort(*.value);返回以下内容:

(Jan => 1 Feb => 2 Mar => 3 Apr => 4 May => 5 Jun => 6 Jul => 7 Aug => 8 Sep => 9 Oct => 10 Nov => 11 Dec => 12)

一旦你有了%months哈希值,这就是一个简单的s///替换(或S///替换,视情况而定)。在前两个代码示例中,-pe使用了自动打印标志。左半部分的匹配s///可以识别所有元素,但是<(...)> “捕获标记”将所有内容放在外面,以便仅捕获日期和字符串月份(将日期放入$0;将月份放入$1)。在运算符的右半部分s///%months哈希值被输入$1变量 key ,如下所示:%months{$1},它告诉哈希值返回键的value。在输出中,日期和月份均采用sprintf.

第三个和第四个代码示例与第一个类似,只是%months哈希值仅声明一次。这些行不是使用-pe-ne命令行标志,而是使用 进行循环for lines()。最后,Raku 注意不要覆盖不可变字符串,因此S///使用大写 S 形式返回结果字符串

示例输出(所有代码示例):

03.01.2023,
12.11.2017,
09.04.2022,

https://raku.org

相关内容