Isso criará arr[0]=hy, arr[1]="hello man"
:
declare -a arr=(hy "hello man")
Eu tenho o 'hy "hello man"' como uma string inteira armazenada em uma variável tal que:
echo "$var"
hy "hello man"
Como posso dividi-lo de volta para uma matriz? Eu tentei IFS= IFS=" " readarray
e tudo, exceto a matriz, só resulta em arr[0]="hy "hello man""
e nãoarr[0]=hy, arr[1]="hello man"
Matriz desejada:
arr[0]=hy arr[1]="hello man"
Para fins de teste:
arg () { printf "%d args:" "$#"; [ "$#" -eq 0 ] || printf " <%s>" "$@"; echo; }
arg hy "hello man"
2 args: <hy> <hello man>
Mas
var='hy "hello man"'
arg $t
1 arg: <hy "hello man">
Existe algum truque de citação que possa ajudar com meu problema?
Se você
bash
é novo o suficiente e já temloadable_builtins
o que incluidsv
, você pode tentar algo assim.Saída
Conforme a saída solicitada pelo OP, a função modificada.
Saída
enable -p
deve mostrar o loadable_builtindsv
help enable
help dsv
Algumas explicações sobre
dsv
e uma alternativa de usosed
Além da resposta correta do Jetchisel , há alguns detalhes.
E como algumas instalações não têm builtins instalados, postei uma alternativa mais forte do que
eval
usarsed
para analisar corretamente a string enviada.1. Uso básico:
Como comentado anteriormente em outros posts,
eval
é malvado !! Para mostrar isso usarei:Então
Sim, para este caso de uso, switches
-S
ou-g
não são necessários.2. Uso
Depois de
help dsv
ler muitas explicações, o parágrafo mais útil é:Abreviado:
3. Sobre
eval
é malSe você tentar a mesma string com uma das outras soluções postadas aqui:
Sugerido por pmf:
O comando então despejará todo o meu arquivo de senhas em uma matriz:
Ou outra resposta, sugerida por Hamidreza Shafizadeh:
Renderizará o mesmo array!
Então você tem que estar confiante com a fonte de conteúdo da variável!!!
4. Alternativa usando
sed
.Se você não tiver o bash-builtins instalado e ainda quiser alguma segurança, você pode usar
sed
from Substitua todas as vírgulas não incluídas entre aspas duplas :4.1. Usando
sed
em uma função.4.1b. O mesmo, citações de limpeza
Sim, coloque aspas duplas em volta de toda a declaração do array (incluindo os parênteses):
Isso restaurará a matriz desejada (as aspas dentro
$var
devem estar sintaticamente corretas):Em contraste, colocar aspas somente ao redor da variável a transformaria em um único elemento:
Resultando na matriz "errada":
Testado com
GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)
Você pode fazer isso da mesma forma que o GNU awk divide registros em campos com sua
FPAT
construção, fazendo um loop sobre a string que corresponde a uma expressão regular que é uma string sem espaços ou uma string entre aspas que pode incluir espaços, por exemplo, usando todos os comandos internos do bash.Ao contrário de algumas outras respostas, a acima não expandiria variáveis ou comandos em
var
. Por exemplo:Usando outra nota de resposta que
$(date)
é executada quandoarr[]
é preenchida:enquanto com esta resposta
$(date)
não for executado:O acima também permite o escape de aspas duplas dentro de strings, da mesma forma que elas podem ser escapadas em CSVs:
Você pode ajustar trivialmente o código para converter
""
s para"
s dentro de strings entre aspas, se desejar.Você também pode se interessar pelas respostas para uma pergunta muito semelhante postada hoje - Capturar campos em uma matriz usando espaços, exceto para strings, usando AWK .
Você pode usar eval para avaliar a string como uma atribuição de matriz.
Cuidado : eval executa a string como código, então se a entrada não for confiável (por exemplo, var='my "Hello world." $(</etc/passwd)'), ela pode ser explorada (agradecimentos a F. Hauri ).
saída:
mas por exemplo, se var fosse o seguinte:
A saída seria algo como isto:
Então, se você sabe o que está em var, a maneira mais fácil é usar eval, caso contrário, use outros métodos sugeridos por outros.