我需要这方面的帮助我有一个以管道分隔的文件,其格式如下
Location|1111|222222|333333|Doe|John|19900723|19900724|19900725
最后 3 个字段是日期字段,但我似乎无法将它们格式化。我需要将它们格式化为1990/07/23。我正在学习 awk,所以我更喜欢通过 awk 来完成它,但我愿意接受建议。
答案1
正如 Kusalananda 评论的那样,你可以做一些字符串操作:
awk -F'|' -v OFS='|' '
function format_date(d) { return substr(d,1,4) "/" substr(d,5,2) "/" substr(d,7) }
{ for (i = 7; i <= 9; i++) $i = format_date($i); print }
' file
答案2
awk -F'|' 'BEGIN {OFS="|"} {print $1,$2,$3,$4,$5,$6,strftime("%Y/%m/%d",$7),strftime("%Y/%m/%d",$8),strftime("%Y/%m/%d",$9)}' inputfile
这里的关键是strftime()
,它将使用第一个参数中的格式字符串格式化第二个参数中提供的日期:
$ echo "1552924174" | awk '{print strftime("%Y/%m/%d", $1) }'
2019/03/18
strftime()
受 GNUawk
和 的支持mawk
,但不受 BSD 的支持awk
。
答案3
我已经通过以下方法完成了
`echo "Location|1111|222222|333333|Doe|John|19900723|19900724|19900725"| awk -F "|" '{$NF=substr($NF,1,4)"/"substr($NF,5,2)"/"substr($NF,7,2);$(NF-1)=substr($(NF-1),1,4)"/"substr($(NF-1),5,2)"/"substr($(NF-1),7,2);$(NF-2)=substr($(NF-2),1,4)"/"substr($(NF-2),5,2)"/"substr($(NF-2),7,2);print $0}'| sed "s/ /`|/g"
输出
echo "Location|1111|222222|333333|Doe|John|19900723|19900724|19900725"| awk -F "|" '{$NF=substr($NF,1,4)"/"substr($NF,5,2)"/"substr($NF,7,2);$(NF-1)=substr($(NF-1),1,4)"/"substr($(NF-1),5,2)"/"substr($(NF-1),7,2);$(NF-2)=substr($(NF-2),1,4)"/"substr($(NF-2),5,2)"/"substr($(NF-2),7,2);print $0}'| sed "s/ /|/g"
Location|1111|222222|333333|Doe|John|1990/07/23|1990/07/24|1990/07/25
答案4
您可以使用Perl
如下所示的方法来完成此操作:
输入:
$ cat file
Location|1111|222222|333333|Doe|John|19900723|19900724|19900725
$ perl -lpe 's#\|\K([0-9]{8})(?=(?:(?:\|[0-9]{8}){0,2})$)#join "/", unpack "A4A2A2", $1#ge' file
Location|1111|222222|333333|Doe|John|1990/07/23|1990/07/24|1990/07/25
解释:
-l
设置 RS = ORS = "\n"-p
使用上面设置的记录分隔符读取记录中的输入文件。此外,在读入下一条记录之前,将当前记录打印到标准输出。-e
Perl
将此选项后面的代码应用于$_
读入的每个记录 ( )。- 在看到行尾之前,它
regex
会找出前面有竖线且后面最多有两个与自身相同种类的邻居的 8 位数字。它们被存储在捕获中$1
。 - 现在,每个捕获的内容
$1
都会根据A4A2A2
模式进行解包,然后将这些模式用斜线连接在一起。
备用:
$ perl -F'[|]' -pale '$_ = join "/", unpack "A4A2A2" for @F[-3..-1]; $_ = join "|", @F'