我正在尝试将日期从一种格式转换为另一种格式: 从例如“2005年10月29日”至2005年10月29日。 我有625个日期列表。我用Awk。
转换有效 - 大部分时间。 Hovewer,有时转换根本不会发生, 应该保持(转换)日期的变量仍然存在 未定义。
这总是发生在完全相同的行上。 在日期上显式地(从Bash shell)运行“date” 这些奇怪的行工作正常(日期被正确转换)。 - 这些行的文本内容不重要。
为什么会出现这种情况,以及如何修复脚本?
她是:
awk 'BEGIN { FS = "unused" } {
x = "undefined";
"date \"+%Y-%m-%d\" -d " $1 | getline x ;
print $1 " = " x
}' uBXr0r15.txt \
> bug-out-3.txt
如果您想重现此问题:
然后你可以再次运行脚本, 和(在我的电脑上)bug-out-3.txt仍然存在 未更改 - 完全相同的日期未定义。
(Gawk 3.1.6版,Ubuntu 9.10。)
亲切的问候,马格努斯
答案 0 :(得分:9)
每当您在awk
中打开管道或文件进行读取或写入时,后者将首先检查(使用内部哈希)是否已有管道或文件同名(仍然)打开;如果是这样,它将重用现有的文件描述符,而不是重新打开管道或文件。
在您的情况下,所有以undefined
结尾的条目实际上都是重复的;第一次遇到它们(即首次发出相应的命令date "..." -d "..."
时),将正确的结果读入x
。在同一日期的后续事件中,getline
尝试从原始date
管道读取第二行,第三行等,即使管道已被date
关闭,也会导致x
{1}}不再被分配。
来自gawk
手册页:
注意:如果使用管道,协同处理或套接字来获取getline,或者 来自循环中的print或printf, 你必须使用close()来创建新的 命令或套接字的实例。 AWK不会自动进行 关闭管道,插座或协同过程 当他们返回EOF时。
每次阅读close
后,您应该明确x
管道:
close("date \"+%Y-%m-%d\" -d " $1)
顺便说一下,sort
和uniq
uBXr0r15.txt
在输入awk
之前是否可以,或者您是否需要原始排序/复制?
答案 1 :(得分:3)
虽然我喜欢awk,但这并不是必需的。
tr -d '"' < uBXr0r15.txt | date +%Y-%m-%d -f -
答案 2 :(得分:3)
gawk 'BEGIN{
m=split("January|February|March|April|May|June|July|August|September|October|November|December",d,"|")
for(o=1;o<=m;o++){
months[d[o]]=sprintf("%02d",o)
}
FS="[, ]"
}
{
gsub(/["]/,"",$1)
gsub(/["]/,"",$4)
t=mktime($4" "months[$1]" "$2" 0 0 0")
print strftime("%Y-%m-%d",t)
}' uBXr0r15.txt
在gawk中执行所有操作将比调用外部命令更快。