我正在使用以下 sed 命令,我想将其转移到 awk 以将日期从2023-12-15更改为15/12/2023:
echo "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details" \
| sed 's/\(....\)-\(..\)-\(..\)/\3\/\2\/\1/g'
导致
c_az_6332,15/12/2023,-24.01,BP_Connect,Particulars,details
如何使用 awk gsub|sub|gensub 执行相同操作?
我尝试过以下方法:
echo "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details" \
| awk -F "," '{gsub(\(....\)-\(..\)-\(..\),\3\/\2\/\1,$2) ; print $0}'
和
echo "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details" \
| awk -F "," '{gsub(/\(....\)-\(..\)-\(..\)/,\3\/\2\/\1,$2) ; print $0}'
两者都不起作用。有人可以帮忙吗?
使用 GNU awk 和
gensub()
:
$ gawk '{
print gensub(/(....)-(..)-(..)/,"\\3/\\2/\\1",1)
}' <<< "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details"
输出:
c_az_6332,15/12/2023,-24.01,BP_Connect,Particulars,details
,
作为输入 (FS
) 和输出 (OFS
) 的字段分隔符:FS = OFS = ","
$2
) 拆分为命名数组:split($2, a, "-")
sprintf
和数组项重新格式化第 2 列:$2 = sprintf("%d/%d/%d", a[3], a[2], a[1])
echo "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details" | awk '
BEGIN { FS = OFS = ","; }
{ split($2, a, "-");
$2 = sprintf("%d/%d/%d", a[3], a[2], a[1]);
print;
}
'
c_az_6332,15/12/2023,-24.01,BP_Connect,Particulars,details
使用 GNU Awk 5.3.0、One True Awk 版本 20231124 和 Mawk 版本 1.3.4 20231126 进行测试。
使用
gnu awk
,您可以使用正则表达式和 3 个捕获组来匹配第二个字段中的类似日期的模式,在匹配连字符的同时捕获数字。
然后使用这些组将第二个字段的值设置为新格式,并用
/
分隔
awk '
BEGIN{FS=OFS=","}
match($0, /([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/, a) {
$2 = a[3] "/" a[2] "/" a[1]
}1' <<< "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details"
输出
c_az_6332,15/12/2023,-24.01,BP_Connect,Particulars,details
为了完善您的日期转换选项,如果您关心添加/删除前导零、在 UTC 和区域设置之间进行转换、添加其他派生指标(如周数、星期几等),您也可以考虑致电
date
进行转换,只需重新插入其结果即可。在这个简单的例子中,执行的命令是 date +%d/%m/%Y -d 2023-12-15
:
echo "c_az_6332,2023-12-15,-24.01,BP_Connect,Particulars,details" \
| awk -F, -vOFS=, '{d="date +%d/%m/%Y -d" $2; d|getline $2; close(d); print;}'
c_az_6332,15/12/2023,-24.01,BP_Connect,Particulars,details
使用 GNU Awk 5.3.0、One True Awk 版本 20231124 和 Mawk 版本 1.3.4 20231126 进行测试。