我正在 FreeBSD 上使用nsxiv查看 JPEG 和 PNG 图像。但是,我无法找到一种按修改时间对图像进行排序和过滤的方法,以便在 FreeBSD 上的 nsxiv 中查看它们。在使用 GNU coreutils 和 GNU findutils 的 Linux 上,我可以使用以下命令查看 2023 年 10 月 1 日之后修改的图像,按修改时间排序。
find . -maxdepth 1 -type f \
\( -iregex '.+\.jpe?g$' -o -iregex '.+\.png$' \) \
-newermt 2023-10-01 \
-exec ls -t --zero -- {} + | \
nsxiv -0 -
我无法在 FreeBSD 上找到能够处理包含空格、换行符和其他异常字符的文件名的等效命令。问题是 FreeBSDls
没有--zero
选项输出 NUL 分隔的文件名以通过管道传输到nsxiv
. 另一个问题是 FreeBSDfind
没有-printf0
可用于获取可传递给sort -z
. 如何按修改时间对图像进行排序和过滤并在 FreeBSD 上的 nsxiv 中查看它们?
我在 Linux 和 FreeBSD 上使用/bin/sh
(dash) /bin/sh
。
您必须正确地通过 xargs 才能完成排序;所以,像
我们使用“装饰 - 排序 - 取消装饰”技巧,您通常会在带有元组的语言中找到这种技巧。在这里,我们需要用空格将排序键(统计中自纪元以来的秒数
%Y
)与值(文件名)分开。然后又cut
回来了。有点尴尬!如果能够在普通的 FreeBSD 系统上运行对您来说很重要,那么还有 find/xargs/cut/stat 的另一个答案。如果您能够安装其他实用程序,那么使用 zsh 也有更清晰的答案。
但是如果你习惯了 GNUism 和 Linux,那么如果你安装了 GNU findutils ,那么在 FreeBSD 上过上舒适的生活是很容易的。
同样,人们也被 BSD ls、grep、make、sed 和 awk 所困扰。但它们的 GNU 对应项以及gnuls、gnugrep、gmake、gsed和gawk都很容易获得。你会全力以赴然后获取coreutils
它们都可以与您系统上的 BSD 版本共存。然后,您通常会在命令前加上 GNU 版本的“g”前缀:
gnuls
、gfind
、gxargs
、gmake
和。gsed
gawk
如果您讨厌为您心爱的 gnu 变体添加前缀,请参阅“如何使 GNU grep 成为 FreeBSD 中的默认值? ”
如果您习惯了 BSD 变体,那么它们也可以在 Linux 上使用。参见bsdutils
你可以这样做:
对于便携性+可靠性,
perl
可能是您最好的选择:-exec ls -t --zero -- {} +
请注意,如果文件列表足够大,需要find
调用ls
多次,则您将无法按修改时间对文件进行正常排序。我找到了一个适用于 FreeBSD 的解决方案
/bin/sh
。我在 FreeBSD 13.2 中尝试过。它似乎可以正确处理包含反斜杠和空格(空格、制表符和换行符)的文件名,包括前导和尾随空格。怎么运行的:
ls -l -B -D%s
-B
以八进制表示法显示不可打印的字符。这对于处理包含换行符和制表符的文件名非常重要。-D%s
格式文件修改时间(自纪元以来的秒数)。这对于按修改时间排序很有用。cut -w -f6-
:从输出中删除除ls -l ...
包含文件修改时间和文件名的列之外的所有列。-w
必须将连续的空格算作一个分隔符。sort -r
:按照修改时间从最近修改到最早修改的顺序对文件进行排序。cut -f2-
:删除文件修改时间列,仅保留(换行符分隔的)文件名。printf
格式%b
字符串将文件名中的八进制表示法转换回实际字符(即包括换行符和制表符)。使用 NULL 字符 (\0
) 分隔文件名,将 NULL 分隔的文件名通过管道传输到nsxiv -0 -
.补充笔记:
cut -w -f6- | sort -r | cut -f2-
ls
不能用 的选项代替-t
。正如用户“Stéphane Chazelas”在此网页的另一个答案中写道:find ... \( -iregex '.\{1,\}\.jpe\{0,1\}g$' -o -iregex '.\{1,\}\.png$' \)
可以通过使用扩展正则表达式来简化。例如find -E ... -iregex '.+\.(jpe?g|png)$'
。-n
以便ls
输出ls
用户 ID 和组 ID 而不是名称。