我有一个包含很多符号链接和一些巨大子目录的目录。我想获得父目录中文件的详细列表(按时间排序),但如果文件是符号链接,则用目标替换链接。
该命令readlink -f * | sort | uniq
处理符号链接。所以你会认为
ls -alt `readlink -f * | sort | uniq`
会简单地按命令输出的时间排序readlink
。但它不仅返回父目录的内容,还返回所有子目录的内容。如何获得所需的输出,即按时间排序的列表仅有的父目录中的文件,并用目标替换链接?感谢您的任何建议。
答案1
与zsh
GNU ls
:
files=(*(NDoN:P))
(($#files)) && ls -ltd -- ${(u)files}
或者为了简洁起见使用匿名函数:
(){ (($#)) && ls -ltd -- ${(u)@}; } *(NDoN:P)
其中N
启用nullglob
,D
dotglob
包含隐藏文件,跳过按 mtime 排序的oN
排序,并执行与 GNU 相同的操作。参数扩展标志删除数组中的重复项。ls
:P
readlink -f
(u)
或者,如果当前目录中有太多文件,则上述操作失败并显示争论太多错误,您可以zsh
进行排序并将列表传递给ls -U
(要禁用其自己的排序,需要 GNUls
或兼容版本),如果需要,可以通过zargs
它将xargs
列表分割成更小的块。
autoload zargs
files=(*(ND-om:P))
zargs -r --eof= -- ${(u)files} '' ls -lUd --
其中-om
符号链接解析后按修改时间排序。
(请注意,当前在解析中具有无限循环的符号链接上zsh
会被阻塞)。:P
使用bash
GNU 工具,您可以执行以下操作:
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
,您将文件列表作为换行符分隔的记录传递给readlink
,sort
因此会破坏包含换行符的文件名。由于您忘记了--
之前的内容*
,因此它也会破坏以 . 开头的文件名-
。
在 中情况要糟糕得多ls -alt `cmd`
,这次 的输出cmd
在空格、制表符和换行符上进行分割(假设 的默认值$IFS
),并且文件名生成是在结果单词上执行的,因此它会阻塞更多的字符。如果没有-d
,ls
还会列出内容它作为参数传递的目录的一部分,而不仅仅是目录本身。
答案2
考虑这种方法:
ls | xargs realpath
ls $PWD | xargs realpath
看看这里为什么它可以在没有以下内容的情况下工作-1
:https://unix.stackexchange.com/a/410557/537347