![如何将用月份名称表示的日期转换为数字月份名称?](https://linux22.com/image/216981/%E5%A6%82%E4%BD%95%E5%B0%86%E7%94%A8%E6%9C%88%E4%BB%BD%E5%90%8D%E7%A7%B0%E8%A1%A8%E7%A4%BA%E7%9A%84%E6%97%A5%E6%9C%9F%E8%BD%AC%E6%8D%A2%E4%B8%BA%E6%95%B0%E5%AD%97%E6%9C%88%E4%BB%BD%E5%90%8D%E7%A7%B0%EF%BC%9F.png)
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,