Encontre o nome do arquivo mais longo

0

Eu tenho que encontrar o link simbólico que contém o nome da pasta mais longa em uma pasta cheia de links simbólicos. Até agora eu tenho isso:

find <folder> -type l -printf "%l\n"

Eu queria saber se existe alguma maneira de salvar os nomes das pastas durante a pesquisa, algo como esse pseudo código:

if [length > max]
{
  max = length
  var = link
}

Obrigado :)

    
por user45124 31.10.2018 / 16:29

2 respostas

0
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." }'

Para tornar o awk mais legível:

BEGIN {
   maxlength = 0
   longest = ""
} 

length( $NF ) > maxlength { 
   maxlength = length( $NF )
   longest = $NF
} 
END { 
   print "longest was", longest, "at", maxlength, "characters." 
}

awk é ótimo para lidar com dados delimitados. Como os caminhos são delimitados por / s, usamos isso como o separador de campo (com a opção -F ), rastreamos o nome mais longo que vimos com uma variável longest e seu comprimento na variável maxlength . Alguns cuidados e alimentação para tornar a saída são, se não forem encontrados links, deixarei como um exercício para o leitor.

    
por 31.10.2018 / 16:33
0

com zsh :

zmodload zsh/stat
by_link_depth() {
  zstat -A REPLY +link -- ${1-$REPLY}
  REPLY=${REPLY//[^\/]}
}

define uma função que retorna as barras no alvo do symlink, então você pode usá-lo como um método de ordenação para seus globs:

ls -ld -- **/*(D@O+by_link_depth[1])

Relacionaria o link simbólico ( @ ), incluindo os ocultos ( D ) com o destino mais profundo ( O+by_link_depth , ordenar inversamente por profundidade do link e [1] seleciona o primeiro).

Aqui em /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*

Se você se importa apenas com o destino de link de profundidade máxima e não com o link simbólico que aponta para ele, é possível executar zstat +link em vez de ls -ld nesse link simbólico ou definir um resolve e by_depth function:

resolve() zstat -A REPLY +link -- ${1-$REPLY}
by_depth() REPLY=${REPLY//[^\/]}

e:

printf '%s\n' **/*(D@O+by_depth+resolve[1])

Em que +resolve converte o symlink em seu destino para a expansão glob e O+by_depth faz a classificação inversa por profundidade.

Com bash (embora o código abaixo não seja de modo algum bash específico) e utilitários GNU (seu -printf já é específico do GNU), você pode conseguir algo próximo com:

find . -type l -printf '%l
find . -type l -printf '%l
zmodload zsh/stat
by_link_depth() {
  zstat -A REPLY +link -- ${1-$REPLY}
  REPLY=${REPLY//[^\/]}
}
' | gawk -v RS='
ls -ld -- **/*(D@O+by_link_depth[1])
' -F / ' NF > max {max = NF; target = $0} END {if (max) print target}'
%p
$ 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*
' | gawk -v RS='
resolve() zstat -A REPLY +link -- ${1-$REPLY}
by_depth() REPLY=${REPLY//[^\/]}
' -v ORS='
printf '%s\n' **/*(D@O+by_depth+resolve[1])
' -F / ' {n = NF; getline; if (n > max) {max = n; file = $0}} END {if (max) print file}' | xargs -r0 ls -ld

Ou apenas para o alvo mais profundo:

find . -type l -printf '%l
find . -type l -printf '%l%pre%' | gawk -v RS='%pre%' -F / '
   NF > max {max = NF; target = $0}
   END {if (max) print target}'
%p%pre%' | gawk -v RS='%pre%' -v ORS='%pre%' -F / ' {n = NF; getline; if (n > max) {max = n; file = $0}} END {if (max) print file}' | xargs -r0 ls -ld
    
por 31.10.2018 / 16:47