title: How to skip a directory in awk?
body: <p>Say I have the following structure of files and directories:</p>
  
  <pre><code>$ tree
  .
  ├── a
  ├── b
  └── dir
      └── c
  
  1 directory, 3 files
  </code></pre>
  
  <p>That is, two files <code>a</code> and <code>b</code> together with a dir <code>dir</code>, where another file <code>c</code> stands.</p>
  
  <p>I want to process all the files with <code>awk</code> (<code>GNU Awk 4.1.1</code>, exactly), so I do something like this:</p>
  
  <pre><code>$ gawk '{print FILENAME; nextfile}' * */*
  a
  b
  awk: cmd. line:1: warning: command line argument `dir' is a directory: skipped
  dir/c
  </code></pre>
  
  <p>All is fine but the <code>*</code> also expands to the directory <code>dir</code> and <code>awk</code> tries to process it.</p>
  
  <p>So I wonder: is there any native way <code>awk</code> can check if the given element is a file or not and, if so, skip it? That is, without using <code>system()</code> for it.</p>
  
  <p>I made it work by calling the external <code>system</code> in <a href="https://www.gnu.org/software/gawk/manual/html_node/BEGINFILE_002fENDFILE.html" rel="nofollow">BEGINFILE</a>:</p>
  
  <pre><code>$ 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
  </code></pre>
  
  <p><sub>Note also the fact that <code>if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}</code> works counter intuitively: it should return 1 when true, but it returns the exit code.</sub></p>
  
  <p>I read in <a href="https://www.gnu.org/software/gawk/manual/html_node/POSIX_002fGNU.html" rel="nofollow">A.5 Extensions in gawk Not in POSIX awk</a>:</p>
  
  <blockquote>
    <ul>
    <li>Directories on the command line produce a warning and are skipped (see <a href="https://www.gnu.org/software/gawk/manual/html_node/Command_002dline-directories.html#Command_002dline-directories" rel="nofollow">Command-line directories</a>)</li>
    </ul>
  </blockquote>
  
  <p>And then the linked page says:</p>
  
  <blockquote>
    <p>4.11 Directories on the Command Line</p>
    
    <p>According to the POSIX standard, files named on the awk command line
    must be text files; it is a fatal error if they are not. Most versions
    of awk treat a directory on the command line as a fatal error.</p>
    
    <p>By default, gawk produces a warning for a directory on the command
    line, but otherwise ignores it. This makes it easier to use shell
    wildcards with your awk program:</p>
  
  <pre><code>$ gawk -f whizprog.awk *        Directories could kill this program
  </code></pre>
    
    <p>If either of the --posix or --traditional options is given, then gawk
    reverts to treating a directory on the command line as a fatal error.</p>
    
    <p>See <a href="https://www.gnu.org/software/gawk/manual/html_node/Extension-Sample-Readdir.html#Extension-Sample-Readdir" rel="nofollow">Extension Sample Readdir</a>, for a way to treat directories as usable
    data from an awk program.</p>
  </blockquote>
  
  <p>And in fact it is the case: the same command as before with <code>--posix</code> fails:</p>
  
  <pre><code>$ 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)
  </code></pre>
  
  <p>I checked the <code>16.7.6 Reading Directories</code> section that is linked above and they talk about <code>readdir</code>:</p>
  
  <blockquote>
    <p>The readdir extension adds an input parser for directories. The usage
    is as follows:</p>
    
    <p>@load "readdir"</p>
  </blockquote>
  
  <p>But I am not sure neither how to call it nor how to use it from the command line.</p>