将 ls -alt 与 readlink 结合起来

将 ls -alt 与 readlink 结合起来

我有一个包含很多符号链接和一些巨大子目录的目录。我想获得父目录中文件的详细列表(按时间排序),但如果文件是符号链接,则用目标替换链接。

该命令readlink -f * | sort | uniq处理符号链接。所以你会认为

ls -alt `readlink -f * | sort | uniq`

会简单地按命令输出的时间排序readlink。但它不仅返回父目录的内容,还返回所有子目录的内容。如何获得所需的输出,即按时间排序的列表仅有的父目录中的文件,并用目标替换链接?感谢您的任何建议。

答案1

zshGNU ls

files=(*(NDoN:P))
(($#files)) && ls -ltd -- ${(u)files}

或者为了简洁起见使用匿名函数:

(){ (($#)) && ls -ltd -- ${(u)@}; } *(NDoN:P)

其中N启用nullglob,D dotglob包含隐藏文件,跳过按 mtime 排序的oN排序,并执行与 GNU 相同的操作。参数扩展标志删除数组中的重复项。ls:Preadlink -f(u)

或者,如果当前目录中有太多文件,则上述操作失败并显示争论太多错误,您可以zsh进行排序并将列表传递给ls -U(要禁用其自己的排序,需要 GNUls或兼容版本),如果需要,可以通过zargs它将xargs列表分割成更小的块。

autoload zargs
files=(*(ND-om:P))
zargs -r --eof= -- ${(u)files} '' ls -lUd --

其中-om符号链接解析后按修改时间排序。

(请注意,当前在解析中具有无限循环的符号链接上zsh会被阻塞)。:P

使用bashGNU 工具,您可以执行以下操作:

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  printf '%s\0' "${files[@]}" | # prints as NUL-delimited records
  xargs -r0 readlink -zf -- |   # get absolute canonical path
  LC_ALL=C sort -zu |           # removes duplicates
  xargs -r0 stat --printf '%.9Y/%n\0' -- | # get mtime with max precision
  sort -rnz |                   # sort numerically in reverse
  cut -zd/ -f2- |               # remove timestamp added earlier
  xargs -r0 ls -lUd --          # pass to as many ls invocations as needed

如果文件列表足够小,则可以简化为:

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  readlink -zf -- "${files[@]}" | # get absolute canonical path
  LC_ALL=C sort -zu |             # removes duplicates
  xargs -r0 ls -ltd --            # pass to ls

了解我们如何始终将文件列表作为 NUL 分隔记录在工具之间传递。 NUL 是唯一不能出现在文件路径中的字符(和字节值),因此是唯一安全的方法。

在 中readlink -f * | sort,您将文件列表作为换行符分隔的记录传递给readlinksort因此会破坏包含换行符的文件名。由于您忘记了--之前的内容*,因此它也会破坏以 . 开头的文件名-

在 中情况要糟糕得多ls -alt `cmd`,这次 的输出cmd在空格、制表符和换行符上进行分割(假设 的默认值$IFS),并且文件名生成是在结果单词上执行的,因此它会阻塞更多的字符。如果没有-dls还会列出内容它作为参数传递的目录的一部分,而不仅仅是目录本身。

答案2

考虑这种方法:

ls | xargs realpath
ls $PWD | xargs realpath

看看这里为什么它可以在没有以下内容的情况下工作-1https://unix.stackexchange.com/a/410557/537347

相关内容