Nomes compostos em um array [RESOLVIDO]

1. Nomes compostos em um array [RESOLVIDO]

Adriano Christi
ACMM

(usa Linux Mint)

Enviado em 12/01/2020 - 18:20h

Tudo bem, galera? Eu ainda estou iniciando em shell script, tenho um conhecimento razoável sobre lógica de programação, desenvolvo algumas coisas em Python e Java (muito mais em Python).
Bom, a ajuda que eu preciso é com esse código abaixo:

#!/bin/bash
drt=/media/SSD2/Python/*
rmv=$[ ${#drt} - 1 ]
c=0

for x in $drt
do
c=$[$c + 1]
if [ -d "$x" ]
then
d+=(${x:$rmv})
elif [ -f "$x" ]
then
arq+=(${x:$rmv})
fi
a+=($x)
done

echo "DIRETÓRIOS: ${d[*]}"
echo "${#d[*]}"
echo
echo "ARQUIVOS: ${arq[*]}"
echo "${#arq[*]}"
echo "${#a[*]}"
echo "$c"


O problema é que quando o script exibe no terminal o total de diretórios, é mostrado 58 ao invés de 37 e é mostrado um total de 238 ao invés de 118. Eu sei que isso é devido ao fato de que quando o array é criado, são contadas as palavras que estão dentro do array e não o nome das pastas como são. Por exemplo, se no diretório eu tiver duas pastas com o nome 'Pasta' e 'Nova pasta', o código vai criar o array 'pasta=(Pasta Nova pasta)' e se eu pedir pra imprimir o total de elementos no array, vai aparecer 3 ao invés de 2.
Como eu faço pra que o código crie o array com elementos de nome composto e seja contado como apenas um elemento?
Eu creio que deu pra entender. Agradeço a ajuda.


  


2. MELHOR RESPOSTA

Perfil removido
removido

(usa Nenhuma)

Enviado em 12/01/2020 - 18:30h

Não sou especilista como muitos aqui mas nesse dois casos, você está pedindo pro Bash só pegar as últimas 31 letras dos nomes dos arquivos.
Se o arquivo/pasta tiver menos que 31 letras no nome, fica em branco.
d+=(${x:31})
arq+=(${x:31})

Para evitar quebrar o nome dentro de um array, use '""':
d+=("${x}")
arq+=("${x}")


Trabalhar com arrays no Z-shell é muito melhor.
Sei que tem casos especiais que se deve usar POSIX, mas para quê ignorar todas as funcionalidades novas do Bash?
In POSIX sh, += is undefined


Você pode listar o número de diretórios usando (se não forem diretórios que começam com '.', do contrário pode adicionar a opção -A):
$ ls -d -1 */ | wc -l 

A opção '-d' é só para se certificar que o Ls vai listar diretórios e a opção '-1' é para listar em apenas uma coluna simples. A sua shell vai interpretar o coringa '*' para listar qualquer arquivo (pastas são meramente um arquivo com um índice de outros arquivos no UNIX). Para o Ls, somente as pastas tem a barra '/' no final do nome.


Para listar o número de arquivos:
$ ls -p -1 |grep -cv '/' 

A opção '-p' do Ls adiciona a barra '/' no final do nome de pastas, assim o grep vai contar '-c' todas as linhas que _não_ contém uma barra, opção '-v'.

3. Re: Nomes compostos em um array

Adriano Christi
ACMM

(usa Linux Mint)

Enviado em 12/01/2020 - 19:38h

marimbondo2 escreveu:

Não sou especilista como muitos aqui mas nesse dois casos, você está pedindo pro Bash só pegar as últimas 31 letras dos nomes dos arquivos.
Se o arquivo/pasta tiver menos que 31 letras no nome, fica em branco.
d+=(${x:31})
arq+=(${x:31})

Para evitar quebrar o nome dentro de um array, use '""':
d+=("${x}")
arq+=("${x}")


Trabalhar com arrays no Z-shell é muito melhor.
Sei que tem casos especiais que se deve usar POSIX, mas para quê ignorar todas as funcionalidades novas do Bash?
In POSIX sh, += is undefined


Você pode listar o número de diretórios usando (se não forem diretórios que começam com '.', do contrário pode adicionar a opção -A):
$ ls -d -1 */ | wc -l 

A opção '-d' é só para se certificar que o Ls vai listar diretórios e a opção '-1' é para listar em apenas uma coluna simples. A sua shell vai interpretar o coringa '*' para listar qualquer arquivo (pastas são meramente um arquivo com um índice de outros arquivos no UNIX), e somente as pastas tem a barra '/' no final do nome para a shell.


Para listar o número de arquivos:
$ ls -p -1 |grep -cv '/' 

A opção '-p' do Ls adiciona a barra '/' no final do nome de pastas, assim o grep vai contar '-c' todas as linhas que _não_ contém uma barra, opção '-v'.




Valeu pela ajuda. Funcionou. Era tão simples e eu quebrando a cabeça...
Quanto a esse detalhe:

d+=(${x:31})
arq+=(${x:31})

Eu coloquei o valor fixo porque no path que eu estava fazendo o teste antes, eu sabia que dava um total de 31 caracteres e resolvi fazer essa gambiarra básica só pra fazer o script funcionar.
É verdade o que disse: se tiver um diretório ou arquivo com menos de 31 caracteres, eu vou ter problemas. Eu já havia resolvido isso da seguinte forma:

drt=/media/SSD2/Python/*
rmv=$[ ${#drt} - 1 ]

E nas partes onde eu preciso "cortar" as strings, fiz assim:

d+=("${x:$rmv}")
arq+=("${x:$rmv}")

Agora está funcionando de boa.
Abraços.





Guns don't kill people. People kill people.


4. Re: Nomes compostos em um array

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 12/01/2020 - 20:45h

ACMM escreveu:

Tudo bem, galera? Eu ainda estou iniciando em shell script, tenho um conhecimento razoável sobre lógica de programação, desenvolvo algumas coisas em Python e Java (muito mais em Python).
Bom, a ajuda que eu preciso é com esse código abaixo:

#!/bin/bash
drt=/media/SSD2/Python/*
c=0

for x in $drt
do
c=$[$c + 1]
if [ -d "$x" ]
then
d+=(${x:31})
elif [ -f "$x" ]
then
arq+=(${x:31})
fi
a+=($x)
done

echo "DIRETÓRIOS: ${d[*]}"
echo "${#d[*]}"
echo
echo "ARQUIVOS: ${arq[*]}"
echo "${#arq[*]}"
echo "${#a[*]}"
echo "$c"

O problema é que quando o script exibe no terminal o total de diretórios, é mostrado 58 ao invés de 37 e é mostrado um total de 238 ao invés de 118. Eu sei que isso é devido ao fato de que quando o array é criado, são contadas as palavras que estão dentro do array e não o nome das pastas como são. Por exemplo, se no diretório eu tiver duas pastas com o nome 'Pasta' e 'Nova pasta', o código vai criar o array 'pasta=(Pasta Nova pasta)' e se eu pedir pra imprimir o total de elementos no array, vai aparecer 3 ao invés de 2.
Como eu faço pra que o código crie o array com elementos de nome composto e seja contado como apenas um elemento?
Eu creio que deu pra entender. Agradeço a ajuda.


Boa noite ACMM.
Segue sugestão.

#!/bin/bash
drt=/media/SSD2/Python/
c=0;
for x in $drt*;do
if [ -d "$x" ];then
d+=("${x/$drt}");
elif [ -f "$x" ];then
arq+=("${x/$drt}");
fi
a[$c]="$x"
let c++;
done
echo -e "DIRETÓRIOS: ${#d[*]}\n"${d[@]}"\n\n\nARQUIVOS: "${#arq[*]}"\n${arq[*]}\n\nTOTAL: $c\nTodos:\n${a[*]}\n"

Outra opção:
drt="/media/SSD2/Python/";
array_dir=("$(find $drt -maxdepth 1 -type d|sed '1d')");
array_files=("$(find $drt -maxdepth 1 -type f)");

echo -e "Diretórios\n";printf "%s\n" "${array_dir[@]}"|nl -v 0 -n rz -w1 -s ' ';
echo -e "Arquivos:\n";printf "%s\n" "${array_files[@]}"|nl -v 0 -n rz -w1 -s ' ';

______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


5. Re: Nomes compostos em um array

Perfil removido
removido

(usa Nenhuma)

Enviado em 12/01/2020 - 22:25h

Para pegar só o nome do arquivo/subdiretório no array da lista, poderia fazer também:
d+=("${x##*/}") 

Off-topic, eu suspeito que o msoliver gosta de escrever código a mais, exemplo a assinatura dele com um 'echo' e um monte de sujeira para ser limpada.. rss Brincadeiras a parte, code golfing é legal, também..


6. Re: Nomes compostos em um array [RESOLVIDO]

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 13/01/2020 - 18:43h

marimbondo2 escreveu:

Off-topic, eu suspeito que o msoliver gosta de escrever código a mais,
exemplo a assinatura dele com um 'echo' e um monte de sujeira para ser limpada.. rss
Brincadeiras a parte,
code golfing é legal, também..


Boa tarde Marimbondo.
Não endendi o que tem a mais no meu código!!!!!
Seria a subistituição: d+=("${x/$drt}") ....

Monte de sujeira para ser limpada.....
Isso é somente um sed pegando um trecho especifico da página....

Sim, sempre que possível e com tempo, procuro fazer o código mais reduzido.
O que não se aplica para usuários iniciantes, nesse caso, procuro fazer o script de forma mais didática, para que o usuário entenda .
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


7. Re: Nomes compostos em um array [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 13/01/2020 - 20:24h

Imagina, msoliver, tantas coisas a mais. Tipo o que eh isso? Nao tinha algo mais facil de assinatura? Eu até hj nao sei o que significa por medo de executar tal comando sinistro...

Na verdade, era zoaeira somente.


8. Re: Nomes compostos em um array [RESOLVIDO]

Adriano Christi
ACMM

(usa Linux Mint)

Enviado em 13/01/2020 - 22:11h

Pessoal, valeu muito a ajuda de vocês dois. Me ajudou bastante.
Aqui, pelo menos, o que eu vi até agora em vários tópicos do fórum, a maioria procura ajudar com respostas simples e diretas ao que se pede e não como em alguns fóruns em que o usuário pergunta quanto é 1 + 1 e os "crânios" fazem uma expressão criada em um computador quântico com muitas firulas só pra responder que o resultado é 2.
Obrigado e abraços.



Guns don't kill people. People kill people.


9. Re: Nomes compostos em um array [RESOLVIDO]

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 13/01/2020 - 22:25h


marimbondo2 escreveu:

Imagina, msoliver, tantas coisas a mais. Tipo o que eh isso?
Nao tinha algo mais facil de assinatura?
Eu até hj nao sei o que significa por medo de executar tal comando sinistro...
Na verdade, era zoaeira somente.


Vamos esclarecer a assinatura:
lynx --dump goo.gl/a9KeFc => Carrega a página "https://www.vivaolinux.com.br/termos-de-uso/"
|sed -nr '/^[ ]+Se/,/dou.$/p' => Pega a linha que começa com " Se" (espaços e a palavra Se), até a linha que termina com "dou."
Mostra:"
Se você sanou sua dúvida ou resolveu um problema a partir de um
tópico criado, é extremamente recomendável que acesse o tópico e
marque-o como "RESOLVIDO". E mais recomendável ainda que você eleja
como melhor resposta a que mais lhe ajudou.

"
Bastante simples...... rsrsrsrsrs
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


10. Re: Nomes compostos em um array [RESOLVIDO]

Adriano Christi
ACMM

(usa Linux Mint)

Enviado em 13/01/2020 - 22:46h

msoliver escreveu:


marimbondo2 escreveu:

Imagina, msoliver, tantas coisas a mais. Tipo o que eh isso?
Nao tinha algo mais facil de assinatura?
Eu até hj nao sei o que significa por medo de executar tal comando sinistro...
Na verdade, era zoaeira somente.


Vamos esclarecer a assinatura:
lynx --dump goo.gl/a9KeFc => Carrega a página "https://www.vivaolinux.com.br/termos-de-uso/"
|sed -nr '/^[ ]+Se/,/dou.$/p' => Pega a linha que começa com " Se" (espaços e a palavra Se), até a linha que termina com "dou."
Mostra:"
Se você sanou sua dúvida ou resolveu um problema a partir de um
tópico criado, é extremamente recomendável que acesse o tópico e
marque-o como "RESOLVIDO". E mais recomendável ainda que você eleja
como melhor resposta a que mais lhe ajudou.

"
Bastante simples...... rsrsrsrsrs
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________


Simples assim.
hahahahahahahahahahahahahaha

Guns don't kill people. People kill people.


11. Re: Nomes compostos em um array [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 13/01/2020 - 23:05h

Tiro o meu chapéu para vocês aqui do fórum.
A assinatura do msoliver é bem legal, na verdade!
Bem explicado! =))






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts