Lê o conteúdo em uma linha no bash

2

Eu tenho um arquivo com o conteúdo nesta ordem, que é separado por espaço

  4096 1230 4560 1024.... n

Como posso ler cada número e passá-lo para outro comando, por exemplo, dividir cada número por 1024.

    
por learner 09.11.2013 / 16:53

5 respostas

3

Enquanto marcados com , o mais simples é read em um array:

bash-4.1$ read -a l < file

Então você pode iterar sobre os valores como este:

bash-4.1$ for n in "${l[@]}"; do echo "$n / 1024 ≈ $((n/1024)) = $(bc -l<<<"$n/1024")"; done
4096 / 1024 ≈ 4 = 4.00000000000000000000
1230 / 1024 ≈ 1 = 1.20117187500000000000
4560 / 1024 ≈ 4 = 4.45312500000000000000
1024 / 1024 ≈ 1 = 1.00000000000000000000
    
por 09.11.2013 / 17:03
2

Contanto que os dados sejam delimitados por espaço, você pode carregar o conteúdo do arquivo em uma matriz da seguinte forma:

arr=$(< data.txt)

Quando os dados forem carregados na matriz, $arr , você poderá usar um loop for para percorrê-lo e realizar sua divisão por 1024.

$ for num in ${arr[*]}; do 
    res=$( expr $num / 1024 )
    echo "$num / 1024 = $res"
  done

Exemplo

$ for num in ${arr[*]}; do res=$( expr $num / 1024 ); echo "$num / 1024 = $res";done
4096 / 1024 = 4
1230 / 1024 = 1
4560 / 1024 = 4
1024 / 1024 = 1

Se você deseja obter resultados de ponto flutuante, em vez de números inteiros, use bc para fazer isso:

$ for num in ${arr[*]}; do 
    res=$(echo "scale=2; $num/1024" |bc)
    echo "$num / 1024 = $res"
  done
4096 / 1024 = 4.00
1230 / 1024 = 1.20
4560 / 1024 = 4.45
1024 / 1024 = 1.00

Você pode controlar o número de casas decimais alterando o valor passado para scale= . Definindo 'scale=5 :

4096 / 1024 = 4.00000
1230 / 1024 = 1.20117
4560 / 1024 = 4.45312
1024 / 1024 = 1.00000

Referências

por 09.11.2013 / 20:02
2

A essência do script de shell é executar o mínimo de comandos possível. Aqui, awk é tipicamente o comando que é melhor projetado para dividir linhas em campos e fazer aritmética:

awk '{for (i = 1; i<= NF; i++) $i = $i/1024; print}' < your-file

Usar loops de shell em shells geralmente é um sinal de prática incorreta de script de shell.

    
por 09.11.2013 / 21:46
2

Para esta simples tarefa aritmética, você pode se ater às construções internas do shell e ligar read para ler e divida a primeira linha ou use a substituição de comando para ler a entrada e dividi-la.

Como alternativa, você pode tratar isso como um problema de processamento de texto e chamar awk para fazer todo o processamento.

Se a sua tarefa real exigir a passagem de cada número para um comando separado, você poderá usar xargs . xargs tem um formato de entrada estranho, mas se sua entrada não tiver nada de \'" você não precisa se preocupar com isso.

<input.txt xargs -n1 somecommand
    
por 10.11.2013 / 20:34
-2

Para listas grandes, geralmente construo um contador para separar uma linha por vez, então qualquer operação variável que você queira executar pode ser feita de forma confiável. Eu tive matrizes grandes (para linha em cat foo.bar ; do) desmoronar .. a saber:

InCt='cat foo.bar|wc -l'
RunCt=1
while [ $InCt -ge $RunCt ]; do
  LINE='head -${RunCt} foo.bar|tail -1'

  # do whatever you need with the line

let RunCt="$RunCt +1"
done
    
por 09.11.2013 / 21:12