我必须在充满符号链接的文件夹中找到包含最长文件夹名称的符号链接。到目前为止我有这个:
find <folder> -type l -printf "%l\n"
我想知道是否有任何方法可以在搜索时保存文件夹名称,例如以下伪代码:
if [length > max]
{
max = length
var = link
}
谢谢 :)
答案1
find /path/to/base -type l | awk -F/ 'BEGIN {maxlength = 0; longest = "" } length( $NF ) > maxlength { maxlength = length( $NF ); longest = $NF } END { print "longest was", longest, "at", maxlength, "characters." }'
为了使内容awk
更具可读性:
BEGIN {
maxlength = 0
longest = ""
}
length( $NF ) > maxlength {
maxlength = length( $NF )
longest = $NF
}
END {
print "longest was", longest, "at", maxlength, "characters."
}
awk
非常擅长处理分隔数据。由于路径由 s 分隔/
,因此我们使用它作为字段分隔符(使用开关-F
),跟踪我们在变量中看到的最长名称longest
及其在变量中的长度maxlength
。如果没有找到链接,我将把一些照顾和反馈留给读者作为练习,以使输出保持理智。
答案2
和zsh
:
zmodload zsh/stat
by_link_depth() {
zstat -A REPLY +link -- ${1-$REPLY}
REPLY=${REPLY//[^\/]}
}
定义一个函数,该函数返回符号链接目标中的斜杠,然后您可以将其用作全局变量的排序方法:
ls -ld -- **/*(D@O+by_link_depth[1])
将列出符号链接 ( @
),包括D
具有最深目标的隐藏符号链接 ( )(O+by_link_depth
按链接深度反向排序,并[1]
选择第一个)。
在此处/usr/bin
:
$ ls -ld -- **/*(D@O+by_link_depth[1])
lrwxrwxrwx 1 root root 59 Oct 9 03:08 mptopdf -> ../share/texlive/texmf-dist/scripts/context/perl/mptopdf.pl
$ ls -lUd -- **/*(D@O+by_link_depth[1,3])
lrwxrwxrwx 1 root root 59 Oct 9 03:08 mptopdf -> ../share/texlive/texmf-dist/scripts/context/perl/mptopdf.pl*
lrwxrwxrwx 1 root root 61 Oct 9 03:09 pkfix-helper -> ../share/texlive/texmf-dist/scripts/pkfix-helper/pkfix-helper*
lrwxrwxrwx 1 root root 60 Oct 9 03:09 mkjobtexmf -> ../share/texlive/texmf-dist/scripts/mkjobtexmf/mkjobtexmf.pl*
如果您只关心最大深度链接目标而不关心指向它的符号链接,您可以运行zstat +link
而不是ls -ld
在该符号链接上,或者您可以定义一个resolve
andby_depth
函数:
resolve() zstat -A REPLY +link -- ${1-$REPLY}
by_depth() REPLY=${REPLY//[^\/]}
和:
printf '%s\n' **/*(D@O+by_depth+resolve[1])
将+resolve
符号链接转换为其 glob 扩展的目标,并按O+by_depth
深度进行反向排序。
使用bash
(尽管下面的代码绝不是bash
特定的)和 GNU 实用程序(你的-printf
已经是 GNU 特定的),你可以得到一些接近的东西:
find . -type l -printf '%l\0%p\0' | gawk -v RS='\0' -v ORS='\0' -F / '
{n = NF; getline; if (n > max) {max = n; file = $0}}
END {if (max) print file}' | xargs -r0 ls -ld
或者仅针对最深的目标:
find . -type l -printf '%l\0' | gawk -v RS='\0' -F / '
NF > max {max = NF; target = $0}
END {if (max) print target}'