gawk / awk:将日期管道传输到 getline *有时*不起作用
我正在尝试将日期从一种格式转换为另一种格式: 例如从“2005年10月29日”到2005年10月29日。 我有 625 个日期的列表。我用awk。
大多数情况下,这种转换是有效的。 然而,有时转换根本不会发生, 并且应该保存(转换后的)日期的变量仍然存在 不明确的。
这种情况总是发生在完全相同的行上。 在日期上显式运行“date”(从 Bash shell) 这些奇怪的行工作正常(日期已正确转换)。 -- 重要的不是这些行的文本内容。
为什么会出现这种行为?如何修复我的脚本?
她是:
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 脚本。
- 在 bug-out-3.txt 中搜索“未定义”。
(在我的电脑上,“undefined”出现了 122 次。)
然后你可以再次运行该脚本, 并且(在我的计算机上)bug-out-3.txt 仍然存在 不变——完全相同的日期未定义。
(Gawk 版本 3.1.6,Ubuntu 9.10。)
亲切的问候, Magnus
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.
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.
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
If you want to reproduce this problem:
- Download this file: uBXr0r15.txt.
- Run the Awk skript.
- Search for "undefined" in bug-out-3.txt.
("undefined" found 122 times, on my computer.)
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 version 3.1.6, Ubuntu 9.10.)
Kind regards, Magnus
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每当您在
awk
中打开管道或文件进行读取或写入时,后者将首先检查(使用内部哈希)它是否已有管道或文件同名(仍然)打开;如果是这样,它将重用现有的文件描述符,而不是重新打开管道或文件。在您的情况下,所有最终为
undefined
的条目实际上都是重复的;第一次遇到它们时(即首次发出相应的命令date "..." -d "..."
时),正确的结果会被读入x
。在后续出现相同日期时,getline
会尝试从原始date
管道中读取第二、第三等行,即使该管道已被关闭date
,导致不再分配x
。来自
gawk
手册页:每次读完 x 后,您都应该显式地
关闭
管道:顺便说一句,
sort
和uniq
可以吗? code>uBXr0r15.txt
在管道输入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.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 commanddate "..." -d "..."
is first issued) the proper result is read intox
. On subsequent occurrences of the same date,getline
attempts to read a second, third etc. lines from the originaldate
pipe, even though the pipe has been closed bydate
, resulting inx
no longer being assigned.From the
gawk
man-page:You should explicitly
close
the pipe every time after you have readx
:Incidentally, would it be OK to
sort
anduniq
uBXr0r15.txt
before piping intoawk
, or do you need the original ordering/duplication?虽然我喜欢 awk,但这并不是必需的。
tr -d '"' < uBXr0r15.txt | 日期 +%Y-%m-%d -f -
Though I love awk it is not necessary for this.
tr -d '"' < uBXr0r15.txt | date +%Y-%m-%d -f -
在 gawk 中执行所有操作都会比调用外部命令更快。
doing everything inside gawk will be faster than calling external commands.