“ls”对应于“find”运算符“-printf”?

“ls”对应于“find”运算符“-printf”?

find命令有一个方便的-printf操作符,可以为每个找到的文件/文件夹打印用户指定的元数据。该命令有这样的选项吗ls

作为替代方案,我可以将感兴趣的文件名列表提供给 find而不是ls,但这似乎就像在飞行中使用大锤一样。我已经有了感兴趣的文件,但我并没有真正“找到”任何东西。

此外,提供路径find会很棘手,因为我不能只将所需的文件路径附加到结尾的一个find 命令。该find命令要求路径运算符(或“谓词”)。因此,我无法轻松利用“xargs”。

谢谢钢铁起子为了他的回答。我认为stat如果我从头开始,他的使用将是一个解决方案。不幸的是,我必须将输出与其他系统(特别是使用find's )生成的类似信息进行比较printf

以下是一些find我发现有效的代码习惯用法:

# Option 1
Some Command \
| xargs -n 1 -I{} find {} -printf '%p\t%TY-%Tm-%Td %TH:%TM\t%s\n'

# Option 2
Some Command | tr '\n' '\0' \
| xargs -0 -I{} find {} -printf '%p\t%TY-%Tm-%Td %TH:%TM\t%s\n'

基于穆鲁的评论,这是一个我还没有开始工作的代码习惯用法,因为我的findCygwin 的 Gnu 版本早于 4.9 并且无法识别谓词-files0-from

Some Command | tr '\n' '\0' \
| find -files0-from - -printf '%p\t%TY-%Tm-%Td %TH:%TM\t%s\n'

答案1

据我所知,在 1的 GNU 实现中并非如此ls,但是在stat.

例如stat,GNU Coreutilsstat --printf '%n\t%y\t%s\n'将为您提供所需的字段和分隔符,尽管它(据我所知)不提供日期时间格式的细粒度控制。

但是,如果zsh是一个选项,您可以使用zsh/stat 模块,也许可以使用您想要的确切输出定义您自己的 shell 函数:

zmodload -F zsh/stat b:zstat

mystat () {
  local f s ret=0
  for f do
    zstat -n -LF '%Y-%m-%d %H:%M' -H s -- $f &&
      printf '%s\t%s\t%s\n' $s[name] $s[mtime] $s[size] ||
      ret=$?
  done
  return $ret
}

或者,您可以使用简单的 perl 脚本来完成您想要的操作lstat函数, 例如

mystat() {
  perl -MPOSIX -E '
    foreach $f (@ARGV) { 
      if (@s = lstat($f)) {
        say join "\t", $f, strftime("%Y-%m-%d %H:%M", localtime($s[9])), $s[7];
      } else {
        warn "$f: $!\n";
        $ret = 1;
      }
    }
    exit $ret;
  ' -- "$@"
}

无论如何,这-printf是特定于 GNU 实现的(尽管在添加findGNU 命令之前就已经存在了几十年)。stat使用 GNU find4.9 或更高版本,您可以使用谓词可靠地传递任意路径列表-files0-from

mystat() {
  [ "$#" -eq 0 ] ||
    printf '%s\0' "$@" |
    find -files0-from - -prune -printf '%p\t%TY-%Tm-%Td %TH:%TM\t%s\n'
}

在任何情况下,请注意 TAB 和 NL 与文件路径中的任何字符一样有效,因此无法可靠地解析输出(可以简化的时间戳格式%F %R也是不明确的,因为它缺少时区信息)。

所有这些都lstat()对文件执行 a 操作,因此对于那些类型符号链接它们报告有关符号链接本身的信息,而不是它们最终解析到的文件的信息。要stat()改为执行此操作(并在符号链接解析后报告信息),请将选项添加-L到 GNUstat或 GNU find,从 zsh stat 中删除它,删除-Past-open 的选项ls,并在脚本中替换lstat为。statperl


¹ 的ast-开放实现虽然与ls -PdZ '%(name)s\t%(mtime:time=%Y-%m-%d %H:%M)s\t%(size)s' -- "$@"(相同的语法对于标准pax命令)但是据我所知,那个不再被维护。

² GNUstat在调用的文件上也会失败,-因为它将其解释为fstat()在 stdin 上执行 a 的意思; zsh stat(比 GNU 早几年)不存在这个问题,并且可以对任意文件描述符-f FD执行 a 操作。fstat()

相关内容