I'd like to find a regular pattern to include in a shell script so that n variables will contain the n arguments
O seguinte cria uma matriz de shell arglist
que contém cada um dos argumentos:
$ readarray -t arglist < <(echo "\command{arg1,
arg2 ,
arg3
}" | sed -n '/\command/{ :a;/}/!{N;b a}; s/\command{//; s/[ \n}]//g; s/,/\n/g; p}')
Usando a declaração declare
, podemos ver que funcionou:
$ declare -p arglist
declare -a arglist='([0]="arg1" [1]="arg2" [2]="arg3")'
Aqui está outro exemplo com os argumentos em uma linha:
$ readarray -t arglist < <(echo "\command{arg1, arg2, arg3, arg4}" | sed -n '/\command/{ :a;/}/!{N;b a}; s/\command{//; s/[ \n}]//g; s/,/\n/g; p}')
Mais uma vez, funciona:
$ declare -p arglist
declare -a arglist='([0]="arg1" [1]="arg2" [2]="arg3" [3]="arg4")'
Observe que o espaço em < <(
é essencial. Estamos redirecionando a entrada de uma substituição de processo. Sem o espaço, bash
tentará algo totalmente diferente.
Como funciona
O comando sed
é um pouco sutil. Vamos ver um pedaço de cada vez:
-
-n
Não imprima linhas, a menos que explicitamente solicitado.
-
/\command/{...}
Se encontrarmos uma linha que contenha
\command
, execute os comandos encontrados nas chaves, que são os seguintes: -
:a;/}/!{N;b a}
Isto lê as linhas no buffer padrão até encontrarmos uma linha que contenha
}
. Desta forma, obtemos o comando inteiro de uma vez. -
s/\command{//
Remova a string
\command{
. -
s/[ \n}]//g
Remova todos os espaços, fechando chaves e novas linhas.
-
s/,/\n/g
Substitua vírgulas por novas linhas. Quando isso é feito, cada argumento está em uma linha separada, que é o que
readarray
quer. -
p
Imprimir.