Maneira eficiente de converter string em aspas simples no array no shell do Linux

0

Exemplo de caso:

$ Array=( "Mary" "had a __SingleQuote__little__SingleQuote__" "lamb" )

$ for i in "${Array[@]}"; do echo "$i"; done
Mary
had a __SingleQuote__little__SingleQuote__
lamb

Eu quero converter a string __SingleQuote__ em um caractere aspas simples ' , portanto, a matriz será:

$ ConvertedArray=( "Mary" "had a 'little'" "lamb" )

$ for i in "${ConvertedArray[@]}"; do echo "$ done
Mary
had a 'little'
lamb

Talvez algo como:

$ ConvertedArray=( "$(echo ${Array[@]} | sed s/___SingleQuote__/\'/ )" )

Mas este comando produz os resultados errados:

$ for i in "${ConvertedArray[@]}"; do echo "$i"; done
Mary had a __SingleQuote__little__SingleQuote__ lamb

Qual é o comando apropriado para fazer isso em um shell Linux (Bash se a solução precisa ser específica)?

Eu poderia implementar um loop, mas o array poderia ser muito longo, então eficiência ao usar ferramentas shell é preferível.

Testado :

  • O comando tr , mas transladata caractere por caractere.
  • O comando 'sed', mas tenho problemas para lidar com aspas simples que a sintaxe 'sed' precisa.
por Sopalajo de Arrierez 02.05.2018 / 02:47

3 respostas

3

Em bash , você deve conseguir aplicar uma substituição de parâmetro global a um elemento de matriz por elemento:

$ Array=( "Mary" "had a __SingleQuote__little__SingleQuote__" "lamb" )
$ ConvertedArray=( "${Array[@]//__SingleQuote__/\'}" )
$ printf '%s\n' "${ConvertedArray[@]}"
Mary
had a 'little'
lamb

Veja, por exemplo, Pesquisar e substituir: Matrizes

    
por 02.05.2018 / 03:00
1

Claro, isso vai imprimir o que você pede:

printf '%s\n' "${Array[@]//__SingleQuote__/\'}"

Mas, como você solicita um novo array com os valores corrigidos, use:

ConvertedArray=( "${Array[@]//__SingleQuote__/\'}" )

Naturalmente, os índices de ConvertedArray serão numéricos de 0 para cima. Isso parece não ser um problema, mas desde que você mencionou nos comentários (em outra resposta) continue lendo.

Matriz esparsa

Se a matriz é definida como:

$ Array=( [2]="Mary" [5]="had a __SingleQuote__little__SingleQuote__" [8]="lamb" )

Em seguida, o array é esparso (tem alguns buracos):

$ declare -p Array
declare -a Array=([2]="Mary" [5]="had a __SingleQuote__little__SingleQuote__" [8]="lamb")

Para resolver isso, você precisa de um loop:

$ for i in "${!Array[@]}"; do
>     ConvertedArray[i]="${Array[i]//__SingleQuote__/\'}"
> done
$ declare -p ConvertedArray
declare -a ConvertedArray=([2]="Mary" [5]="had a 'little'" [8]="lamb")

e

$ printf '%s\n' "${ConvertedArray[@]}"
Mary
had a 'little'
lamb    
    
por 02.05.2018 / 08:17
1

Eu estou supondo que você está querendo fazer isso em bash (ou você não estaria usando uma matriz para começar).

$ echo "${Array[@]//__SingleQuote__/\'}"
Mary had a 'little' lamb
$ printf '%s\n' "${Array[@]//__SingleQuote__/\'}"
Mary
had a 'little'
lamb
$ ConvertedArray=( "${Array[@]//__SingleQuote__/\'}" )
$ printf '%s\n' "${ConvertedArray[@]}"
Mary
had a 'little'
lamb

O texto acima usa a substituição de padrão ${parameter//pattern/text} para substituir todas as ocorrências de __SingleQuote__ por uma única cotação. Quando aplicada a uma matriz, a operação é executada em cada elemento individualmente.

Em um shell POSIX, em que só temos uma matriz, $@ :

set -- "Mary" "had a __SingleQuote__little__SingleQuote__" "lamb"

i=0
while [ "$i" -ne "$#" ]; do
    set -- "$@" "$( printf '%s\n' "$1" | sed "s/__SingleQuote__/'/g" )"
    shift
    i=$(( i + 1 ))
done

printf '%s\n' "$@"

Isso modifica o conjunto de parâmetros posicionais, alimentando cada parâmetro individual por meio de sed para converter a string de espaço reservado em um caractere de aspas simples. Ele faz a modificação no primeiro parâmetro posicional e adiciona o resultado ao final de $@ . Em seguida, ele desloca o primeiro parâmetro da matriz e repete até que todos os elementos tenham sido processados.

O texto acima produziria

Mary
had a 'little'
lamb
    
por 02.05.2018 / 08:00