这是输入.csv文件
"item1","10/11/2017 2:10pm",1,2, ...
"item2","10/12/2017 3:10pm",3,4, ...
.
.
.
现在,我想将第二列(日期)转换为此特定格式
date -d '10/12/2017 2:10pm' +'%Y/%m/%d %H:%M:%S'
,以便" 10/12/2017 2:10 pm" 转换为" 2017/10/12 14:10:00&# 34;
期待输出文件
"item1","2017/10/11 14:10:00",1,2, ...
"item2","2017/10/12 15:10:00",3,4, ...
.
.
.
我知道可以使用bash或python来完成,但我想在单行命令中完成。有任何想法吗?有没有办法将date
结果传递给sed
?
答案 0 :(得分:3)
单行awk
方法。
awk -F',' '{gsub(/"/,"",$2); cmd="date -d\""$2"\" +\\\"%Y/%m/%d\\ %T\\\"";
cmd |getline $2; close(cmd) }1' OFS=, infile #>>outfile
"item1","2017/10/11 14:10:00",1,2, ...
"item2","2017/10/12 15:10:00",3,4, ...
这将输出终端中的更改,如果需要记录输出,则需要将输出重定向到文件,或使用FILENAME
将输出重定向到输入infile
本身。
awk -F',' '{gsub(/"/,"",$2); cmd="date -d\""$2"\" +\\\"%Y/%m/%d\\ %T\\\"";
cmd |getline $2; close(cmd); print >FILENAME }' OFS=, infile
或者GNU awk
实现支持-i inplace
标识符进行就地替换。见'awk' save modifications in place
答案 1 :(得分:1)
你可以在一行中完成,但这引出了一个问题 - “你想要多长时间?”由于你标记为'shell'
而不是bash等,因此你的字符串处理有点受限。 POSIX shell提供了足够的功能来执行您想要的操作,但它并不是最快速的补救措施。您最终会得到一个调用awk
的{{1}}或sed
解决方案或一个调用date
或awk
来解析旧日期的shell解决方案原始文件并将结果提供给sed
以获取您的新日期。你必须找出最有效的补救办法。
就单行而言,您可以执行与以下类似的操作,同时保持POSIX兼容。它只是使用date
从文件中获取第二个awk
,将结果传递给field
循环,该循环使用while
来获取长度并在{{1}内使用从原始日期expr length "$field"
的末尾删除双引号,然后expr substr "$field" "2" <length expression - 2>
获取olddt
,最后date -d "$olddt" +'%Y/%m/%d %H:%M:%S'
执行替换。你的单行(为了便于阅读,显示了自动续行)
newdt
示例输入文件
sed -i "s;$olddt;$newdt;"
生成的文件
$ awk -F, '{print $2}' timefile.txt |
while read -r field; do
olddt="$(expr substr "$field" "2" "$(($(expr length "$field") - 2))")";
newdt=$(date -d "$olddt" +'%Y/%m/%d %H:%M:%S');
sed -i "s;$olddt;$newdt;" timefile.txt; done
可能有更快的方法,但这是一个合理的长度单行(相对而言)。
答案 2 :(得分:0)
修改不那么丑陋的sed
方法:
sed 's/^.*,"\|",.*//g;h;s#.*#date "+%Y/%m/%d %T" -d "&"#e;H;g;s#\n\|$#,#g;s/^/s,/' input.csv | sed -f - input.csv
展开,(它的工作方式相同):
sed 's/^.*,"\|",.*//g
h;
s#.*#date "+%Y/%m/%d %T" -d "&"#e;
H;
g;
s#\n\|$#,#g;
s/^/s,/' input.csv | sed -f - input.csv
输出:
"item1","2017/10/11 14:10:00",1,2, ...
"item2","2017/10/12 15:10:00",3,4, ...
工作原理:
第一个sed
数据块使用 e 评估命令运行date
,其输出为用于生成一些新的sed
s ubstitute 命令。要显示新的 s 命令,请使用|
评论临时替换shell脚本#
管道:
s,10/11/2017 2:10pm,2017/10/11 14:10:00,
s,10/12/2017 3:10pm,2017/10/12 15:10:00,
这些是通过管道输送到第二个sed
。