Orientação do que estudar para saber resolver este problema

1. Orientação do que estudar para saber resolver este problema

Ede
ede_linux

(usa Ubuntu)

Enviado em 17/05/2016 - 21:15h

Olá,

Sou novo no shell script. Já crio uns scripts mas basicamente são com comandos que já conheço :) Com a parte de algoritmia no ambiente de shell script já me sinto à vontade. Para este projecto estou a ter dificuldades pois não sei fazer esta parte que passo a explicar:

Tenho um ficheiro .txt que tem +/- 800 000 linhas com esta estrutura!


.
└── raiz

1 directory
.
├── [ 16K] ./raiz
│   ├── [ 12K] ./raiz/tgdf
│   │   ├── [6.0K] ./raiz/tgdf/a_fazer
│   │   ├── [7.5K] ./raiz/tgdf/a_fazer_5
│   │   ├── [7.9M] ./raiz/tgdf/analise_.pdf
│   │   ├── [241K] ./raiz/tgdf/141.pdf
│   │   ├── [ 18M] ./raiz/tgdf/Aulas.pdf
....


O que preciso de fazer é:
1-Criar um array chamado valores;
2-Ler o ficheiro e importar os valores de cada linha (a linha toda) para o indice do array;
3-O valor do array chamado valores será outro array, chamado info_linha;
4-No indice do array info_linha será colocado o que estiver depois da última barra /;
5-O valor deste último array receberá o que estiver no meio dos caracteres [...] - por exemplo: 6.0K;

Basicamente terei um array multidimensional.
A parte que não sei fazer é ler("varrer") o documento, captar o que estiver depois do última barra (ao aprender a fazer este último aprendo a captar o que estiver entre [...] - digo eu:P)
Agradeço orientação sobre o que devo estudar para aprender a fazer isto. Estou a ler um livro sobre shell script. Mas sinto-me um pouco perdido. E estou um pouco apertado no que toca a tempo deste projecto. Também já estive a ler sobre expressões regulares, que pelo que percebo será extremamente importante para este tipo de problema, certo?

Caso não tenha conseguido explicar correctamente por favor avisem que tento novamente explicar. Obrigado


  


2. Re: Orientação do que estudar para saber resolver este problema

Ronaldo Ferreira de Lima
textmode

(usa Slackware)

Enviado em 18/05/2016 - 14:15h

Se entendi, só falta você usar um laço
while 
iterando pelas linhas do arquivo. Exemplo:


while IFS=$'\n' read line; do # itera linha a linha do arquivo
[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] # testa uma expressão regular
[[ ${#BASH_REMATCH[*]} -lt 3 ]] && continue # se a regexp falhou, pula a linha
IFS=$'\n/' read -a path <<< "${BASH_REMATCH[2]}" # cria um vetor com os elementos do path
echo ${path[-1]} # "cospe" na tela o último elemento do path
done < seu_arquivo_com_8e5_linhas.txt


Há outras formas bem mais simples de coletar o último elemento, porém, menos maleáveis. Exemplos:


sed '\@^.*/\([^/]\+\)$@!d;s//\1/' seu_arquivo_com_8e5_linhas.txt



awk -F'/' 'NF>2{print $NF}' seu_arquivo_com_8e5_linhas.txt


[]'s
--
"Não manejo bem as palavras
Mas manipulo bem as strings."
------------------------------
https://perspicazsite.wordpress.com



3. Re: Orientação do que estudar para saber resolver este problema

Ede
ede_linux

(usa Ubuntu)

Enviado em 18/05/2016 - 19:00h

Obrigado pela resposta,
Para ser sincero não percebi nada :P Mas penso que seja por não saber expressões regulares. Mas vamos lá!

O que faz o IFS? É a variável que vai receber o valor de cada linha?

while IFS=$'\n' read line; do # itera linha a linha do arquivo
[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] # testa uma expressão regular
[[ ${#BASH_REMATCH[*]} -lt 3 ]] && continue # se a regexp falhou, pula a linha
IFS=$'\n/' read -a path <<< "${BASH_REMATCH[2]}" # cria um vetor com os elementos do path
echo ${path[-1]} # "cospe" na tela o último elemento do path
done < seu_arquivo_com_8e5_linhas.txt


Esta parte verifica o que? Se a linha tem conteúdo?

[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] # testa uma expressão regular
[[ ${#BASH_REMATCH[*]} -lt 3 ]] && continue # se a regexp falhou, pula a linha


Aqui penso que carrega o path para a variável patch! Certo? Mas como ele saberá distinguir/delimitar apenas o path do ficheiro?

IFS=$'\n/' read -a path <<< "${BASH_REMATCH[2]}" # cria um vetor com os elementos do path


Nota: Eu não percebo bolha de expressões regulares. Apenas estou a tentar ver a lógico do código pela lógica do algoritmo :P


4. Re: Orientação do que estudar para saber resolver este problema

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 19/05/2016 - 00:13h

ede_linux escreveu:

Olá,

Sou novo no shell script. Já crio uns scripts mas basicamente são com comandos que já conheço :) Com a parte de algoritmia no ambiente de shell script já me sinto à vontade. Para este projecto estou a ter dificuldades pois não sei fazer esta parte que passo a explicar:

Tenho um ficheiro .txt que tem +/- 800 000 linhas com esta estrutura!


.
&#9492;&#9472;&#9472; raiz

1 directory
.
&#9500;&#9472;&#9472; [ 16K] ./raiz
&#9474;   &#9500;&#9472;&#9472; [ 12K] ./raiz/tgdf
&#9474;   &#9474;   &#9500;&#9472;&#9472; [6.0K] ./raiz/tgdf/a_fazer
&#9474;   &#9474;   &#9500;&#9472;&#9472; [7.5K] ./raiz/tgdf/a_fazer_5
&#9474;   &#9474;   &#9500;&#9472;&#9472; [7.9M] ./raiz/tgdf/analise_.pdf
&#9474;   &#9474;   &#9500;&#9472;&#9472; [241K] ./raiz/tgdf/141.pdf
&#9474;   &#9474;   &#9500;&#9472;&#9472; [ 18M] ./raiz/tgdf/Aulas.pdf
....


O que preciso de fazer é:
1-Criar um array chamado valores;
2-Ler o ficheiro e importar os valores de cada linha (a linha toda) para o indice do array;
3-O valor do array chamado valores será outro array, chamado info_linha;
4-No indice do array info_linha será colocado o que estiver depois da última barra /;
5-O valor deste último array receberá o que estiver no meio dos caracteres [...] - por exemplo: 6.0K;

Basicamente terei um array multidimensional.
A parte que não sei fazer é ler("varrer") o documento, captar o que estiver depois do última barra (ao aprender a fazer este último aprendo a captar o que estiver entre [...] - digo eu:P)
Agradeço orientação sobre o que devo estudar para aprender a fazer isto. Estou a ler um livro sobre shell script. Mas sinto-me um pouco perdido. E estou um pouco apertado no que toca a tempo deste projecto. Também já estive a ler sobre expressões regulares, que pelo que percebo será extremamente importante para este tipo de problema, certo?

Caso não tenha conseguido explicar correctamente por favor avisem que tento novamente explicar. Obrigado

__________________________________________________
Boa noite ede_linux
PROBLEMAS:
Não é aceito o nome da variável iniciando com Números ou contendo pontos.
CONFIRME:
O que você deseja é que as seguintes VARIÁVEIS sejam geradas?
tgdf=12K
a_fazer=6.0K
a_fazer_5=7.5K
analise_.pdf=7.9M
141.pdf=241K
Aulas.pdf=18M

É isso?

O que esta depois da ultima barra, é o nome do arquivo:
basename ./raiz/tgdf/analise_.pdf
analise_.pdf

DICA:
USE ls -lr ao invés de tree

Att.:
Marcelo Oliver



5. Re: Orientação do que estudar para saber resolver este problema

Ede
ede_linux

(usa Ubuntu)

Enviado em 19/05/2016 - 11:19h

Oliver,

O que preciso é que deste conteúdo:

.
&#9492;&#9472;&#9472; raiz_

1 directory
.
&#9500;&#9472;&#9472; [ 16K] ./prfw_
&#9474; &#9500;&#9472;&#9472; [ 12K] ./prfw_/C0
&#9474; &#9474; &#9500;&#9472;&#9472; [ 98K] ./prfw_/dfs/index.html
&#9474; &#9474; &#9500;&#9472;&#9472; [6.0K] ./prfw_/dfs/a_asdf
&#9474; &#9474; &#9500;&#9472;&#9472; [7.5K] ./prfw_/dfs/a_asfd_5
&#9474; &#9474; &#9500;&#9472;&#9472; [7.9M] ./prfw_/dfs/asdfsaf.pdf
&#9474; &#9474; &#9500;&#9472;&#9472; [241K] ./prfw_/dfs/asfasfsdc.pdf
&#9474; &#9474; &#9500;&#9472;&#9472; [ 18M] ./prfw_/dfs/sdf dsf.pdf
&#9474; &#9474; &#9500;&#9472;&#9472; [ 116] ./prfw_/dfs/backup.txt
.....continua até ao fim das 180 000 linas


Acabe com este:

values= [&#9474; &#9474; &#9500;&#9472;&#9472; [ 98K] ./prfw_/dfs/index.html]
[info_line=[index.html][98K]]
values= [&#9474; &#9474; &#9500;&#9472;&#9472; [6.0K] ./prfw_/dfs/a_asdf]
[info_line=[a_asdf][6.0K]]


Obrigado


6. Re: Orientação do que estudar para saber resolver este problema

Ronaldo Ferreira de Lima
textmode

(usa Slackware)

Enviado em 19/05/2016 - 11:43h

ede_linux escreveu:

Obrigado pela resposta,
Para ser sincero não percebi nada :P Mas penso que seja por não saber expressões regulares. Mas vamos lá!

O que faz o IFS? É a variável que vai receber o valor de cada linha?


Usei esse primeiro IFS apenas por garantia de que o separador de argumentos seja apenas o caractere de nova linha e para facilitar as próximas possíveis modificações.


while IFS=$'\n' read line; do # itera linha a linha do arquivo
[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] # testa uma expressão regular
[[ ${#BASH_REMATCH[*]} -lt 3 ]] && continue # se a regexp falhou, pula a linha
IFS=$'\n/' read -a path <<< "${BASH_REMATCH[2]}" # cria um vetor com os elementos do path
echo ${path[-1]} # "cospe" na tela o último elemento do path
done < seu_arquivo_com_8e5_linhas.txt


Esta parte verifica o que? Se a linha tem conteúdo?

[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] # testa uma expressão regular
[[ ${#BASH_REMATCH[*]} -lt 3 ]] && continue # se a regexp falhou, pula a linha

[/quote]
O primeiro teste apenas aplica a expressão regular na linha para inicializar a variável $BASH_REMATCH.
O segundo teste verifica se a expressão regular casou com o conteúdo, saltando para a próxima linha caso negativo.


Aqui penso que carrega o path para a variável patch! Certo? Mas como ele saberá distinguir/delimitar apenas o path do ficheiro?

IFS=$'\n/' read -a path <<< "${BASH_REMATCH[2]}" # cria um vetor com os elementos do path


Justamente pela manipulação da variável IFS.


Nota: Eu não percebo bolha de expressões regulares. Apenas estou a tentar ver a lógico do código pela lógica do algoritmo :P


Eu usei apenas itens comuns das man pages e info e também são citados na documentação disponível na web. É interessante também aprender a depurar scripts pelo uso do 'set -x' e também verificando as estruturas de dados criados (variáveis escalares e arrays) que você consegue usando o comando 'set'. Tente começar usando o 'set -x' e verifique como os comandos são executados. Em seguida, faça uso do comando 'set' para verificar como as variáveis são preenchidas, o local mais apropriado seria após o
[[ "$line" =~ ^\ +(.*)\ +(\.\/.*)$ ]] 
, adicionando uma linha como esta:

set | grep '^BASH_REMATCH' 


isto irá deixar o comportamento das expressões regulares "visíveis".


[]'s
--
"Não manejo bem as palavras
Mas manipulo bem as strings."
------------------------------
https://perspicazsite.wordpress.com



7. Re: Orientação do que estudar para saber resolver este problema

Ede
ede_linux

(usa Ubuntu)

Enviado em 19/05/2016 - 12:20h

Obrigado pela ajuda,

O que aconselham para ler? Vou pesquisar esses termos no google mas gostava de saber se existe alguma documentação.
Obrigado, brevemente darei noticias :)


8. Re: Orientação do que estudar para saber resolver este problema

Ronaldo Ferreira de Lima
textmode

(usa Slackware)

Enviado em 19/05/2016 - 12:50h

ede_linux escreveu:

Obrigado pela ajuda,

O que aconselham para ler? Vou pesquisar esses termos no google mas gostava de saber se existe alguma documentação.
Obrigado, brevemente darei noticias :)


* Assumindo que o que passei estava ao menos "no caminho".

Faltou uma fase de análise para identificar o que era necessário para executar a tarefa, você passou direto para a fase de implementação se preocupando apenas com manipulação das variáveis. Os itens que você deveria ter observado primeiro eram:

1. "Como iterar as linhas de um arquivo?" ou "Como ler um arquivo linha a linha?" etc.
2. "Como separar as strings de cada linha em variáveis?"

A partir daqui, você poderia buscar as possíveis implementações mais úteis para o seu caso. No item 1, saber ler um arquivo seria suficiente. Exemplos:

a)
cat arquivo | while read linha; do echo $linha;done 


b)
 while read linha; do echo $linha; done < arquivo 


Cada um tem suas particularidades.

No item 2, você poderia ter usado uma grande série de opções, desde 'sed' até expansão de parâmetros. Eu usei regexp porque ficou mais fácil para mim, mas todos estes itens precisam ser levados em consideração junto com outros aspectos como performance, segurança e manutenibilidade.

Começando primeiro pela parte analítica, a solução fica independente de tecnologia e é capaz de atender corretamente aos requisitos em qualquer caso. Você fica livre para escolher inúmeras soluções bem como simplificar o trabalho em caso de limitações de qualquer tipo. Como exemplo, caso você não soubesse resolver o item 1, a pergunta num fórum de discussão seria muito mais simples e mais pessoas ajudariam, mas ao mesmo tempo, encontrar a resposta já pronta na web seria mais simples também.

[]'s
--
"Não manejo bem as palavras
Mas manipulo bem as strings."
------------------------------
https://perspicazsite.wordpress.com







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts