代码之家  ›  专栏  ›  技术社区  ›  Roger Costello

如何迭代所有文件夹及其子文件夹,并让AWK处理子文件夹中的每个TXT文件?

  •  0
  • Roger Costello  · 技术社区  · 3 周前

    我想遍历所有文件夹及其子文件夹,并打印的名称。TXT文件(在子文件夹中),其第一行包含字符串CYCLE DATE(CYCLE和DATE之间可能有空格和/或下划线)。以下是我解决这个问题的尝试:

    在files_and_folders.sh中,我输入了以下内容:

    #!/bin/bash
    find . -name '*.TXT' -exec awk 'NR == 1 && $0 ~ /CYCLE[_ ]+DATE/ { print FILENAME }'
    

    在bash命令行中,我输入了以下内容:

    bash files_and_folders.sh
    

    这产生了以下错误消息:

    find: missing argument to -exec
    

    正确的方法是什么?

    2 回复  |  直到 3 周前
        1
  •  1
  •   Marcus Müller    3 周前

    我把这个问题分成这样:

    1. 浏览所有文件
    2. 对于每个文件:
      1. 只得到第一行
      2. 检查 CYCLE DATE
      3. 如果找到,则打印文件名。

    所以,

    #!/bin/bash
    # Don't error on no file name matches:
    shopt -s nullglob
    # Enable recursive ** glob:
    shopt -s globstar
    
    for file in **/*.TXT ; do
      # first line only   # look for regex              # print file name
      #                   #  -q:   silently             #
      # -n 1: one line    #  -E: extended regexes       #
      head -n 1 "${file}" | grep -q -E 'CYCLE[_ ]+DATE' && echo "${file}"
      # or your elegant:
      # awk 'NR == 1 && $0 ~ /CYCLE[_ ]+DATE/ { print FILENAME }' "${file}"
    done
    

    当然,而不是 grep 你可以使用 awk 分析你的台词,但坦率地说,这在这里是不必要的复杂。你的正则表达式非常简单(CYCLE,然后是“space”(至少一次),然后是DATE),所以像grep这样的简单正则表达式引擎可以完成这项工作。


    你的问题 find 你两者都不用吗 ';' 也没有 '{}' 之后 -exec ,所以 找到 无法理解它应该在哪里执行命令(或者在执行调用时应该把找到的文件放在哪里)。

    但既然这甚至没有 需要 找到 我个人认为,完全不需要 for file in GLOB; do … done 比记忆更容易 find -name 'PATTERN' -exec Some complicated syntax '{}' ';' .