GAWK / AWK:管道日期函数getline * *有时会无法正常工作 [英] gawk / awk: piping date to getline *sometimes* won't work
问题描述
我试图日期从一种格式转换为另一种:
例如从2005年10月29日为2005-10-29。
我有625日期列表。我用awk。
I'm attempting to convert dates from one format to another: From e.g. "October 29, 2005" to 2005-10-29. I have a list of 625 dates. I use Awk.
改建工程 - 大部分的时间。
Hovewer,有时转换不会发生在所有,
和变量应该保存(转换)日期遗体
不确定的。
The conversion works -- most of the time. Hovewer, sometimes the conversion won't happen at all, and the variable supposed to hold the (converted) date remains undefined.
这总是以完全相同的行发生。
在日期运行'日期'明确(从Bash shell中)
这些怪异的行工作正常(日期将被正确转换)。
- 这不是那些行的文本内容的事项
This always happens with the exact same rows. Running `date' explicitly (from the Bash shell) on the dates of those weird rows works fine (the dates are properly converted). -- It's not the textual contents of those rows that matters.
为什么这种行为,我怎么能修复我的脚本?
她是:
Why this behavior, and how can I fix my script?
Her it is:
awk 'BEGIN { FS = "unused" } {
x = "undefined";
"date \"+%Y-%m-%d\" -d " $1 | getline x ;
print $1 " = " x
}' uBXr0r15.txt \
> bug-out-3.txt
如果您想重现此问题:
- 下载此文件: uBXr0r15.txt
- 运行awk的skript。
- 搜索中的bug外3.txt不确定。结果
(未定义发现122倍,我的电脑上。)
然后,你可以再次运行该脚本,
和(我的电脑上)的bug外3.txt遗体
不变的 - 完全一样的日期没有定义
Then you could run the script again, and (on my computer) bug-out-3.txt remains unchanged -- exactly the same dates are left undefined.
(Gawk的版本3.1.6,Ubuntu 9.10的。)
(Gawk version 3.1.6, Ubuntu 9.10.)
亲切的问候,马格努斯
推荐答案
当你在 AWK
打开读取或写入管道或文件,后者会首先检查(使用内部散)的是否已经有一个管道或具有相同名称的文件(仍然)开放;如果是这样,将重新使用现有的文件描述符而不是重新打开管道或文件。
Whenever you open a pipe or file for reading or writing in awk
, the latter will first check (using an internal hash) whether it already has a pipe or file with the same name (still) open; if so, it will reuse the existing file descriptor instead of reopening the pipe or file.
在你的情况,这最终成为所有条目未定义
实际上是重复;第一次,他们遇到时(即相应的命令日期...-d...
首次颁发)的正确的结果被读入 X
。同日的后续事件,函数getline
尝试读取第二,从原来的最新第三等行
管,即使管已经被日期
,致使 X
不再被分配。
In your case, all entries which end up as undefined
are actually duplicates; the first time that they are encountered (i.e. when the corresponding command date "..." -d "..."
is first issued) the proper result is read into x
. On subsequent occurrences of the same date, getline
attempts to read a second, third etc. lines from the original date
pipe, even though the pipe has been closed by date
, resulting in x
no longer being assigned.
在 GAWK
手册页:
请注意:如果使用的是管道,合作过程中,或插座函数getline,或者
从打印或printf在循环内,
您必须使用close()来创建新
命令或插座的实例。 AWK不会自动
关闭管道,插座,或协同进程
当他们返回EOF。
NOTE: If using a pipe, co-process, or socket to getline, or from print or printf within a loop, you must use close() to create new instances of the command or socket. AWK does not automatically close pipes, sockets, or co-processes when they return EOF.
您应该明确地关闭
每次管您已经阅读后 X
:
You should explicitly close
the pipe every time after you have read x
:
close("date \"+%Y-%m-%d\" -d " $1)
顺便说一句,那会是确定排序
和 uniq的
uBXr0r15.txt
管道进入 AWK
,或者你需要原始排序/复制?
Incidentally, would it be OK to sort
and uniq
uBXr0r15.txt
before piping into awk
, or do you need the original ordering/duplication?
这篇关于GAWK / AWK:管道日期函数getline * *有时会无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!