6

有没有办法让awk (gawk) 忽略或跳过丢失的文件?也就是说,通过命令行传递的文件不再存在于文件系统中(例如,/proc/[1-9]* 下快速出现/消失的文件)。

默认情况下,丢失文件是致命错误:-(

我希望能够做类似这样的事情:

BEGIN { MISSING_FILES_ARE_FATAL = 0 }  # <- Wishful thinking!
      { count++ }
END   { print count }

包装脚本无法在 awk 运行之前检查文件是否存在,因为它们可能会在检查它们和 awk 尝试打开它们之间消失,即,这是一个竞争条件。(在 awk 中 check-and-then-open 也是一种竞争条件,虽然时间比较紧)

4

6 回答 6

2

GAWK 4 可以BEGINFILE在其中测试ERRNO并执行nextfileif ERRNOis not empty(表示无法打开文件)。

于 2012-09-10T11:22:57.233 回答
1

即使在你的 awk 脚本周围贴上 perl 或 shell 包装器,我认为仍然会有竞争条件。例如,使用 ADEpt 原本很好的 shell 片段:

[ -r "$filename" ] && awk -f ... $filename

没有什么可以阻止进程在 -r 和 awk 尝试打开文件的时间之间消失......

我能想到的唯一答案是使用 LD_PRELOAD 替换 awk 的系统打开调用,这样如果文件丢失,则会打开 /dev/null 上的读取文件描述符。

那可能行得通...

于 2008-10-20T09:35:57.583 回答
1

那么您可以通过系统调用检查 的内容ARGV,然后通过getline.

 if (system("test -r " ARGV[1]) == 0)
   while ( (getline aline < ARGV[1]) >0 )
     # process ARGV[1] via `aline` instead of $0

...

然后处理 ARGV[2] 等 HTH

于 2008-10-20T09:48:51.723 回答
1

在我看来,“MISSING_FILES_ARE_FATAL = 0”功能将成为下一个 gawk 版本的一部分。查看当前 gawk-stable 源代码的 ChangeLog 文件:

--- 剪断 ---

2008 年 8 月 22 日星期五 14:43:49 阿诺德 D.罗宾斯

* io.c (nextfile): Users Strong In The Ways Of The Source can use
non-existant files on the command line without it being a fatal error.

--- 剪断 ---

http://cvs.savannah.gnu.org/viewvc/gawk-stable/ChangeLog?revision=1.87&root=gawk&view=markup

赫尔曼

于 2009-01-07T13:06:26.780 回答
0

按照最好的传统,我将使用 Perl 程序回答您的 awk 问题。

#!/usr/bin/perl -w

for my $file (@ARGV) {
    open my $fh, $file or next;
    while(<$fh>) {
        ...do your thing here...
    }
}

(这不是 awk,但它是唯一没有竞争条件的解决方案。)

于 2008-10-20T01:05:39.627 回答
0

哦对不起。忽略我之前的回答。这是另一个建议:

cat /proc/[1-9]* 2>/dev/null | awk ....

Cat 将吞噬所有文件,无论是丢失的还是现有的,cat 的错误将被遗忘(丢失的文件对 cat 来说是非致命错误),并且 awk 将能够处理结果。

于 2008-10-21T22:14:29.783 回答