如何计算由空字符分隔的文件数,如通过 find . -type f -print0 返回的数?

如何计算由空字符分隔的文件数,如通过 find . -type f -print0 返回的数?

摘录自man find

-print0

正确;打印完整文件名在标准输出上,后跟一个空字符(而不是 -print 使用的换行符)。这样,处理 find 输出的程序就可以正确解释包含换行符或其他类型空格的文件名。此选项对应于 xargs 的 -0 选项。

因此,如果(例如)您想要查找并删除目录中早于最新 10 个的文件,则可以使用(信用@pLumo):

find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 gio trash

但是,在执行此命令之前,您如何计算即将被删除的文件的数量?

答案1

使用grep,它可以处理由空字符分隔的行:

find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d  | grep -zc .

man grep

-z, --null-data
      Treat input and output data as sequences of lines, each terminated by a  zero  byte
      (the ASCII NUL character) instead of a newline.  Like the -Z or --null option, this
      option can be used with commands like sort -z to process arbitrary file names.

因此,如果(例如)您想要查找并删除目录中早于最新 10 个的文件,则可以使用...

不,你不能。find的输出不能保证按照创建、修改、访问或任何其他顺序进行(除非有一个按 排序-depth,但这与此无关)。

你需要类似这样的东西:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -Vrz | sed -z '1,10d; s/^[[:digit:].]* //'

它使用修改时间(使用 打印为 unix 时间戳)%T@,并按此进行排序,使用-V版本排序作为一般浮点排序的代理,最后使用 删除时间戳sed

答案2

保留同一行并打印删除文件后的文件数量:

find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 bash -c 'gio trash $*;echo $# files trashed'

或者您可以独立计算行数。只需返回正常的行尾(print而不是print0删除-z)。

find . -maxdepth 1 -type f -print | sort -r | sed  1,10d | wc -l

答案3

创建一个按降序排列文件的索引数组;最新文件在索引 0 上,或者ls -rt按升序排列文件。

$ eval "a=($(ls -t --quoting-style=shell-escape))"


从第 n 个文件打印到末尾:

(使用具有偏移量的降序数组|--|xxxx|将防止循环意外吃掉您的文件)。

$ printf %s\\n "${a[@]:10}"

从开始到第 n 个文件打印:

$ printf %s\\n "${a[@]:0:10}" # or "${a[@]::10}"
                       ^ ^
                  offset length

从头开始打印第 n 个文件:

$ printf %s\\n "${a[@]:5:1}"

打印倒数第 n 个文件:

$ printf %s\\n "${a[@]:(-5):1}"

打印以空字符结尾的文件列表:

$ printf %s\\0 "${a[@]:10}" | xargs -0 -n 1

脚本示例如何在循环中使用它;

#!/bin/bash

eval "a=($(ls -t --quoting-style=shell-escape))"
for b in "${a[@]:10}"; do
      ls "$b"
done

相关内容