我有一个这样的文件:
A345435;3/12/2016
D564565;12/29/2017
...
我试图把文件拿到这个:
A345435;20160312
D564565;20171229
...
我试过AWK,但我得到第一部分确定,日期总是一样。
awk 'BEGIN {FS=OFS=";"} {"date -d"$2" +%Y%m%d" | getline newDate; close(newDate); print $1,newDate}'
A345435;20160312
D564565;20160312
...
是不是真的有必要使用AWK,但我想避免的是循环文件,因为它有~20k行。
答案 0 :(得分:3)
您只需要:
$ awk -F'[;/]' '{printf "%s;%s%02d%02d\n",$1,$4,$2,$3}' file
A345435;20160312
D564565;20171229
答案 1 :(得分:2)
你只是重新排列现有的字符串;你不必通过日期功能或外部程序进行转换
awk 'BEGIN {FS=OFS=";"}
{split($2, mdy, "/");
print $1, sprintf("%4d%02d%02d", mdy[3], mdy[1], mdy[2]);
}' datafile
分成几行以便于阅读 - 如果你愿意,你可以放一行
答案 2 :(得分:0)
我不知道awk
,但可以sed
sed -e 's@;\([[:digit:]]\)/@;0\1/@' -e 's@/\([[:digit:]]\)/@/0\1/@' \
-e 's@;\([[:digit:]]\+\)/\([[:digit:]]\+\)/\([[:digit:]]\+\)@;\3\1\2@' yourfile
第一个表达式需要任意一天,并在它们前面加上0,第二个表达式在几个月内表示相同,第三个表达式在日,月和年中取三个数字,并根据需要对它们进行格式化。我使用了' @'标志而不是正常的' /'作为sed
命令的分隔符,因为' /'出现在需要匹配的模式中。
答案 3 :(得分:0)
这样的事情可能有用,虽然可能有更好的方法。
sed -E 's/;([0-9])\//;0\1\//;s/\/([0-9])\//\/0\1\//;s/([0-9]*)\/([0-9]*)\/([0-9]*)/\3\1\2/g' your_file > new_file
它执行三个正则表达式替换:第一个找到一位数的月份并且预先设置为0,第二个找到一位数的天数并且预先设置为0,然后第三个执行mm-dd-yyyy到yyyymmdd之间的转换。 / p>
答案 4 :(得分:0)
以下是使用bash
和date
而不是awk
的解决方案。 date
实用程序的参数没有很好地标准化,因此我们有Linux和非Linux的替代代码路径(例如Mac等BSD变体)。
#!/usr/bin/env bash
while IFS=';' read -ra line; do
line_id=${line[0]}
if [[ $(uname -s) == Linux ]]; then
line_date=$(date -d "${line[1]}" +%Y%m%d)
else
line_date=$(date -j -f %m/%d/%Y "${line[1]}" +%Y%m%d)
fi
echo "$line_id;$line_date"
done < test_file
A345435;3/12/2016
D564565;12/29/2017
> bash test_bash_date
A345435;20160312
D564565;20171229