awk 命令在 find 语句中不起作用

awk 命令在 find 语句中不起作用

我编写了脚本,该脚本假设查找名称中包含数字和点或@tmp 的所有目录,按日期对其进行排序,然后保存在变量的第三个语句结果中。但这总是给我第一个查询结果。我怎样才能得到正确的结果?

TL;DR 我想按日期对匹配的目录进行排序并打印该列表中的第三个目录名称

OLDDATA=`find . \( -name '*@tmp' -o -regex '.*/[0-9.]+' \) -exec ls -t {} + | awk "NR==3 { print }" `

ls -t 结果示例

./1.2.3.4.5.6.102: ./1.2.3.4.5.6.101: ./1.2.3.4.5.6.100: ./1.2.3.4.5.6.99:
./1.2.3.4.5.6.98: ./1.2.3.4.5.6.97: ./1.2.3.4.5.6.96: ./1.2.3.4.5.6.95:
./1.2.3.4.5.6.94: ./1.2.3.4.5.6.93: ./1.2.3.4.5.6.92: ./1.2.3.4.5.6.91:
./1.2.3.4.5.6.90: ./1.2.3.4.5.6.89: ./1.2.3.4.5.6.88: ./1.2.3.4.5.6.87:

答案1

在您的特定情况下,正确的陈述应如下所示:

find . \( -name '*@tmp' -o -regex '.*/[0-9.]+' \) -exec ls -t {} \; | awk 'NR==3'

答案2

我可能会采用这种方法(为了可读性分成几行;只需将它们连接在一起即可得到一行):

ls -td $(
    find . -maxdepth 1 -type d \( -name '@tmp' -o -regex '.*/[0-9.]+' \)
) |
    sed -n '3{p;q}'

这会找到匹配的目录名称,按日期顺序列出它们,然后仅打印该列表中的第三个条目。 (在这种情况下,使用lsfrom 对输出进行排序find是可以接受的,因为我们可以确保所有路径名都不包含空格或任何其他尴尬的字符。在一般情况下,这是一个错误的假设。)

它不会匹配任何以冒号 ( :) 结尾的目录(但也不会匹配您问题中的原始 RE)。


我认为解释一下为什么你最初的陈述没有实现(我认为是)你既定的目标可能会有用。

让我们看一下find

find . \( -name '*@tmp' -o -regex '.*/[0-9.]+' \) -exec ls -t {} +

这会匹配名称以数字 .. 或点结尾@tmp或仅由数字0..9或点组成的文件或目录.。当找到与这两种模式匹配的文件或目录时,会将其添加到列表中。该列表不一定包含您的所有匹配项,并且你不应该假设它确实如此。当列表“足够长”时,它会被传递到ls -t.您可能会执行两次或多次ls -t,每次执行都会排序并列出一组不同的文件和目录名称。

在我的系统上,ls -t首先列出文件,按修改日期降序排列。它们按修改日期降序对目录名称进行排序,并为每个目录名称打印名称及其内容(也按日期降序排序)。要省略您需要使用的内容ls -td

为了安全起见,您甚至不能使用find ... -type d ... -exec ls -dt {} +,因为您无法知道有多少目录名称将传递到 表示的列表{}

让我们看一下awk

awk "NR==3 { print }"

这很好,尽管我倾向于在{ print; exit}打印第三个项目后立即停止处理。

相关内容