【发布时间】:2016-03-05 05:42:09
【问题描述】:
假设我有以下文件和目录结构:
$ tree
.
├── a
├── b
└── dir
└── c
1 directory, 3 files
即两个文件a 和b 以及一个目录dir,其中另一个文件c 所在。
我想用awk(GNU Awk 4.1.1,确切地说)处理所有文件,所以我这样做:
$ gawk '{print FILENAME; nextfile}' * */*
a
b
awk: cmd. line:1: warning: command line argument `dir' is a directory: skipped
dir/c
一切都很好,但* 也扩展到目录dir 和awk 尝试处理它。
所以我想知道:awk 是否有任何原生方式可以检查给定元素是否为文件,如果是,则跳过它?也就是说,不使用system()。
我通过在BEGINFILE 中调用外部system 使其工作:
$ gawk 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, FNR}' * */*
a
a 10
a.wk
a.wk 3
b
b 10
dir
dir is a dir, skipping
dir/c
dir/c 10
还要注意if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile} 的工作原理是直观的:它应该在 true 时返回 1,但它会返回退出代码。
我在A.5 Extensions in gawk Not in POSIX awk读到:
- 命令行上的目录会产生警告并被跳过(请参阅Command-line directories)
然后链接页面说:
4.11 命令行上的目录
根据 POSIX 标准,在 awk 命令行上命名的文件 必须是文本文件;如果不是,这是一个致命错误。大多数版本 awk 将命令行上的目录视为致命错误。
默认情况下,gawk 会在命令上为目录生成警告 行,否则忽略它。这使得使用 shell 更容易 awk 程序的通配符:
$ gawk -f whizprog.awk * Directories could kill this program如果给出了 --posix 或 --traditional 选项中的任何一个,则 gawk 恢复为将命令行上的目录视为致命错误。
请参阅Extension Sample Readdir,了解将目录视为可用目录的方法 来自 awk 程序的数据。
事实上就是这样:与之前使用--posix 相同的命令失败:
$ gawk --posix 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, NR}' * */*
gawk: cmd. line:1: fatal: cannot open file `dir' for reading (Is a directory)
我查看了上面链接的16.7.6 Reading Directories 部分,他们谈论的是readdir:
readdir 扩展为目录添加了一个输入解析器。用途 如下:
@load "readdir"
但我不知道如何调用它,也不知道如何从命令行使用它。
【问题讨论】: