bash + como mudar para a próxima string na lista

1

A lista a seguir representava os tokens entre sdb e sd$MAX (enquanto MAX intervalo poderia ser c - z )

Por exemplo:

MAX=z
list=$(eval echo sd{b..$MAX})
echo $list

strings são: (exemplo)

sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm sdn sdo sdp sdq sdr sds sdt sdu sdv sdw sdx sdy sdz

minha pergunta como mudar a lista de cada loop para a próxima string

exemplo:

for i in disk1 disk2 disk3 disk4 ..................
do
echo $i    <...syntax...>
done

saída esperada

disk1   sdb
disk2   sdc
disk3   sdd
disk4   sde
.
.
.
    
por yael 15.01.2018 / 19:07

4 respostas

0

É melhor usar variáveis de matriz:

#!/bin/bash

MAX=d
eval list=\( $(echo sd\{b..$MAX\})\)
eval disks=\( $(echo disk\{1..${#list[@]}\})  \)

for((i=0;i<=${#list[@]};i++));do
    echo "${disks[i]} ${list[i]}"
done

Em execução:

$ ./script
disk1 sdb
disk2 sdc
disk3 sdd

Adapte conforme necessário.

    
por 15.01.2018 / 21:31
3

Você pode usar indirection para fazer um loop sobre os índices da matriz em vez de seus valores diretamente, por exemplo,

Dado

$ list=(sd{a..f})
$ echo "${list[@]}"
sda sdb sdc sdd sde sdf

então

$ for i in "${!list[@]}"; do printf '%s %s\n' "disk${i}" "${list[$i]}"; done
disk0 sda
disk1 sdb
disk2 sdc
disk3 sdd
disk4 sde
disk5 sdf

Se você realmente quiser fazer do seu jeito, então você precisará extrair um índice inteiro utilizável dos elementos das strings que você está dando um loop, por exemplo. removendo a string principal disk usando a substituição de parâmetro:

for d in disk1 disk2 disk3 disk4; do printf '%s %s\n' "$d" "${list[${d##disk}]}"; done
disk1 sdb
disk2 sdc
disk3 sdd
disk4 sde
    
por 15.01.2018 / 19:23
0

Você pode criar um contador para coluna de disco a partir da lista & substituir strings para uso como exportação

-bash-4.4$ MAX=z
-bash-4.4$ list=$(eval echo sd{b..$MAX})
-bash-4.4$ echo $list
sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm sdn sdo sdp sdq sdr sds sdt sdu sdv sdw sdx sdy sdz
-bash-4.4$  disk=1 ; for i in $(echo $list) ; do echo $i | sed 's/sd./disk'$disk'\t &/' ; disk=$(($disk +1)) ; done
disk1    sdb
disk2    sdc
disk3    sdd
disk4    sde
disk5    sdf
disk6    sdg
disk7    sdh
disk8    sdi
disk9    sdj
disk10   sdk
disk11   sdl
disk12   sdm
disk13   sdn
disk14   sdo
disk15   sdp
disk16   sdq
disk17   sdr
disk18   sds
disk19   sdt
disk20   sdu
disk21   sdv
disk22   sdw
disk23   sdx
disk24   sdy
disk25   sdz
-bash-4.4$ 

tenha cuidado aqui eu uso um disco variável define para contar & a \ t (tabulação) como separador; você pode adaptar-se às suas necessidades se preferir um espaço ou outra coisa.

se você quiser obter essa saída em um arquivo, adicione um redirecionamento de saída & é claro que em um script você pode querer usar o código como este (sem;)

disk=1 
for i in $(echo $list) 
do 
  echo $i | sed 's/sd./disk'$disk'\t &/' ; disk=$(($disk +1))
done > file

esta é a maneira fácil de entender isso. Um método melhor é usar a substituição bash em vez de sed veja o método bash $ {! list [@]} & comando printf ou $ {parameter / pattern / string} funções avançadas de substituição ...

    
por 15.01.2018 / 19:24
0

O Bash tem dois recursos internos simples e diretos que juntos resolverão seu problema: set e shift .

set $list atribuirá cada elemento de $ list a um dos parâmetros posicionais .

shift renomeia todos os parâmetros posicionais $ n + 1 a $ n, efetivamente excluindo $ 1 e "deslocando" todos os parâmetros posicionais para frente.

Então, no seu exemplo, sua declaração echo $i <...syntax...> seria echo $i " " $1; shift .

BTW, pessoalmente, eu usaria printf do bash em vez de echo em outro lugar para o problema echo pode dar a você): printf "%s %s\n" $i $1; shift

    
por 15.01.2018 / 21:17

Tags