Um script em vez de uma função. Isso imprime o número de caracteres no nome de arquivo mais longo, que é o que eu entendi que você queria:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "" ]; then
# move to that directory
cd ""
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( (${#i} > $long) )) && long=${#i}
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%s\n" "Not a directory"
fi
Isso faz uso da configuração dotglob
, o que faz com que globbing com *
inclua arquivos ocultos. Para ver o efeito disso, execute esses comandos em seu diretório inicial:
ls -d *
shopt -s dotglob
ls -d *
Para desativar as configurações de shopt
, use -u
, por exemplo, shopt -u dotglob
.
Precisamos verificar se o argumento é um diretório, então usamos if
e o comando test
(em seu [
form) que tem um teste para diretórios, -d
:
if [ -d "" ]; then
isso significa que, se o primeiro argumento passado ao script for o nome de um diretório existente, faça o seguinte. é o primeiro argumento, e o colocamos entre aspas duplas para impedir que o shell execute outras expansões no valor da variável.
Precisamos entrar no diretório, porque precisamos obter o comprimento do nome do arquivo, não o caminho inteiro (absoluto ou relativo). Nós não queremos isso:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
porque se contarmos o comprimento de $i
, obteremos o comprimento do caminho completo. Poderíamos fazer algumas artimanhas de processamento de texto (e talvez alguns truques mais inteligentes que eu não conheço) para me livrar do caminho, mas analisar nomes de arquivos geralmente não é confiável e se mudarmos de diretório podemos facilmente obter o shell para contar caracteres usando ${#var}
para dar o comprimento de var
(acredito que isso contenha caracteres e não bytes). Observe que os scripts são executados em um shell filho, não no shell atual, portanto, se um script mudar de diretório, o diretório de trabalho do shell que chama o script não é afetado.
Meu script usa for
para percorrer os arquivos no diretório. A linha que faz o trabalho é
(( (${#i} > $long) )) && long=${#i}
Isso significa que, se o comprimento do valor atual de i
for maior que o valor atual de long
, atribua o comprimento de i
a long
. Como primeiro definimos long
para 0, o primeiro nome de arquivo sempre será maior que long
(porque é o mais curto possível). Posteriormente, somente o tamanho dos nomes de arquivos mais longos poderá substituir o valor de long
. Como sabemos que ${#i}
e long
contêm apenas números inteiros, não precisamos protegê-los com aspas duplas. ((
cria um contexto aritmético no Bash para que possamos usar >
com seu significado matemático (graças ao muru para apontar isso para mim em outro lugar).