【问题标题】:Can't seem to search just first line of text似乎无法仅搜索第一行文本
【发布时间】:2016-06-13 22:45:04
【问题描述】:

我使用以下内容仅在文件的第一行中搜索报告名称。它正在搜索整个文件。我以为 NR==1 只会搜索第一行。我想我只是语法不好。

find /SYM/SYM000/REPORT/ -type f -mmin -480 \
  -name '[0-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec awk '/My Report Title/,NR==1 {print FILENAME; exit}' {} \;

感谢任何帮助。

我只想返回文件名。它以 6 位数字作为文件名掩码查找过去 8 小时。

【问题讨论】:

  • 如果你想要的只是文件名,为什么要用awk在文件中搜索呢? Find 的-print 选项将打印文件名。
  • 应该是/My Report Title/ && NR==1
  • 标题在第一行,这就是我需要 awk 的原因。感谢 hek2mgl 完美!

标签: unix awk find aix


【解决方案1】:

hek2gml's answer 包含关键指针 - 您必须使用 && 进行逻辑与 而不是 范围 - 但该命令可以在两个方面更有效:

  • 给定输入文件的短路处理,以便处理在第一行之后停止。
  • 通过使用+ 而不是\; 终止-exec 主文件,将(通常)所有 文件传递​​给单个 awk 调用
find /SYM/SYM000/REPORT/ -type f -mmin -480 \
  -name '[0-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec awk '/My Report Title/ { print FILENAME } { nextfile }' {} +

此命令只查看每个输入文件的第一行。


nextfile 并非严格符合 POSIX,因此如果您的 awk 没有它(GNU Awk、Mawk 和 BSD/OSX Awk 没有 - 不确定 AIX),请使用(效率较低,因为它必须读取每个文件的所有行):

find /SYM/SYM000/REPORT/ -type f -mmin -480 \
  -name '[0-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec awk 'FNR == 1 && /My Report Title/ { print FILENAME }' {} +

如果在没有nextfile 的情况下,您宁愿调用awk每个文件一次-exec 终止符\;),就像在最初的解决方案尝试中一样(读取仅每个文件的第一行,但为每个文件调用一次awk):

find /SYM/SYM000/REPORT/ -type f -mmin -480 \
  -name '[0-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec awk '/My Report Title/ { print FILENAME } { exit }' \;

【讨论】:

  • 如果没有nextfile 命令,这可能会使情况变得更糟,因为它需要扫描文件的所有行而不仅仅是第一行。然而,使用nextfile 命令它可能会显示出稍微更好的性能,因为awk 只会根据需要被调用,但不是针对每个文件。无论如何,我怀疑{} + 是否可移植。看看同事苹果,不!
  • @hek2mgl:是的,但这被 single awk 调用的效率所抵消,因为 + - 在这种情况下很难说哪个更好(取决于文件大小、磁盘速度……)。 nextfile 绝对是要走的路,但我不知道 AIX 的 awk 实现是否有它。我添加了带有\; 和(单)文件短路的替代解决方案。
  • @EdMorton: -exec ... \; 调用每个文件的命令; -exec ... + 调用它时使用尽可能多的命令行(通常是全部;如xargs)。我已经为我的答案添加了一个基于\; 的替代方案,以防nextfile 不可用。总的来说,最有效的组合是nextfile + -exec ...+
  • 我错了:我错过了 Apple 上当前文件夹的点,这是 GNU 查找的默认设置。 {} + 语法有效。
  • @hek2mgl:是的,-exec ...+ 可移植的 - 见pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
【解决方案2】:

看起来您假设/My Report Title/,NR==1 将是一种由, 分隔的条件列表。这个假设是错误的。

在这种情况下,正确的做法是使用 逻辑 AND 运算符&& 连接条件:

find /SYM/SYM000/REPORT/ -type f -mmin -480 \
  -name '[0-9][0-9][0-9][0-9][0-9][0-9]' \
  -exec awk '/My Report Title/ && NR==1 {print FILENAME; exit}' {} \;

【讨论】:

    猜你喜欢
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    相关资源
    最近更新 更多