bash - Alterar linha por linha Interativamente

0

Eu sou novo no bash scripting. Eu quero criar um script interativo que é o usuário prompt para inserir dados para editar um arquivo linha por linha.

O cenário: - Leia um arquivo e faça uma iteração sobre cada linha, eu uso for in

  • Pergunte ao usuário se deseja editar ou não a linha

  • Se sim, faça a edição

  • Se não, continue para a próxima linha

  • Finalize a interação depois que tudo terminar.

Minha abordagem:

# --> get file contents and convert them to an array
readarray thearray < ips.info

# --> Iterate the array and do interactive editing
for item in ${!thearray[@]}; do
 if [[ "$item" == 0 ]]; then
    echo -e "First line: ${thearray[$item]}. Change this line? (y/n)"
    read Useranswer
    if [ $Useranswer = y]; then
        echo "Please type any string:"
        read Firststring    
    elif [ $Useranswer = n]; then
        # not sure what to write here to resume 
    fi
fi
done
echo "Everything done!"

Existe algum erro no meu código acima e como continuar se o usuário pressionar n no teclado?

    
por KeepMove 21.12.2015 / 09:55

3 respostas

2

você pode usar o comando no-op (não fazer nada), no shell ele é :

elif [ $Useranswer = n]; then
    : 
fi

caso contrário, você pode usar o comando exit , que é usado para finalizar scripts. O comando pode ter um intervalo de status de saída de 0 a 255. Apenas exit 0 significa sucesso, todos os outros códigos de status de saída descrevem algum tipo de falha (que não é o que você precisa). Além disso, você pode fazer o seguinte também:

elif [ $Useranswer = n]; then
    exit 0
fi

Mas, neste caso, o resto do script não será executado porque a saída realmente encerra o script neste ponto, assim, por exemplo: se o usuário pressionar "n", você nunca obterá a saída de echo "Everything done!

    
por 21.12.2015 / 10:37
0

Aqui está a minha solução:

# --> get file contents and convert them to an array
readarray thearray < test1

# --> Iterate the array and do interactive editing
declare i=1;
#printf "%s\n" "${thearray[@]}"

while [ $i -le  ${#thearray[@]} ]; do
    echo $i
    echo -e "First line: ${thearray[$i]}. Change this line? (y/n)"
    read Useranswer
    if [ $Useranswer == "y" ]; then

        echo "Please type any string:"
        read Firststring
        thearray[$i]="${Firststring}"
        let i=$i+1
    elif [ $Useranswer == "n" ]; then
        let i=$i+1
        echo $i
    fi
done
echo "printing results\n"
printf "%s\n" "${thearray[@]}"

echo "Everything done!"

Eu mantenho o readarray , o que é bastante óbvio e funciona bem.

Em seguida, declaro i e defino-o como 1 e ele me ajudará a fazer um loop no array.

Eu então uso um loop while , iterando até que i não seja mais baixo ou igual ao tamanho da matriz ${#thearray[@]} .

sua sintaxe ${!thearray[@]} não está correta porque é usada para matriz associativa para obter a lista de todo o valor associado. Não está funcionando no array indexado.

Em seguida, exibo o prompt para alterar o elemento atual da matriz [$ i]. Se a resposta for sim, então eu li a resposta e configurei a matriz [$ i] para esse valor E eu aumento em um meu i . Se não, eu só aumento em 1 i .

ao sair do loop, eu exibo novamente o array para mostrar a mudança.

Você pode salvá-lo de volta ao original se quiser salvá-lo.

    
por 21.12.2015 / 11:03
0

Acho que isso vai fazer o que você pediu

#!/usr/bin/env bash

# --> get file contents and convert them to an array
readarray thearray < ips.info

# --> Iterate the array and do interactive editing

for item in ${!thearray[@]}; do
    echo "Line number: "$item
    echo "line contents: "${thearray[$item]}
    echo -n "Change this line? (y/n)"
    read Useranswer
    if [ $Useranswer = y ]; then
        echo -n "Please type any string:"
        read Firststring
        # insert new value into array
        thearray[$item]=$Firststring
    elif [ $Useranswer = n ]; then
        # not sure what to write here to resume 
        :
    fi
done
declare -p thearray
echo "Everything done!"
    
por 21.12.2015 / 11:14