É assim que eu sugiro que você faça isso, e eu vou explicar o porquê, mas primeiro eu quero falar sobre outra coisa ...
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
Muitas das outras soluções oferecidas aqui parecem sugerir que você pode de alguma forma afetar o conteúdo de uma variável de shell alterando seus métodos de expansão. Posso assegurar-lhe que este não é o caso.
string="some stuff here \
some more stuff here."
echo $string ${#string}
echo "$string" "${#string}"
OUTPUT
some stuff here some more stuff here. 53
some stuff here some more stuff here. 53
O que você vê acima é primeiro uma expansão de divisão de campo, depois um relatório sobre a contagem de bytes da variável de origem da expansão, uma expansão delimitada por aspas e a mesma contagem de bytes. Embora a saída possa diferir o conteúdo da variável% shell,$string
nunca muda, exceto na atribuição.
Além do mais, se você não entende por que isso acontece, você provavelmente encontrará algumas surpresas desagradáveis, mais cedo ou mais tarde. Vamos tentar de novo, mas em condições ligeiramente diferentes.
IFS=sf
echo $string ${#string}
echo "$string" "${#string}"
Mesmo $string
- ambiente diferente.
OUTPUT
ome tu here ome more tu here. 53
some stuff here some more stuff here. 53
A divisão de campo ocorre com base nos delimitadores de campo definidos em $IFS
. Existem dois tipos de delimitadores - $IFS
whitespace e $IFS
mais alguma coisa. Por padrão, $IFS
recebe o valor espaço newline da guia - quais são os três possíveis valores% espaço em branco$IFS
. Ele é facilmente alterado, como você pode ver acima, e pode ter efeitos drásticos em expansões de divisão de campo.
$IFS
whitespace será eliminado por sequência em um único campo - e é por isso que echo
ing uma expansão contendo qualquer seqüência de espaços quando $IFS
contém um espaço será avaliado apenas por um espaço único - porque echo
concatena seus argumentos em espaços. Mas qualquer valor que não seja espaço em branco não será elidido da mesma maneira, e cada delimitador que ocorre sempre terá um campo em si - como pode ser visto na expansão coisas acima.
Este não é o pior de tudo. Considere este outro $string
.
IFS=$space$tab$newline
cd emptydir
string=" * * * \
* * * "
echo $string ${#string}
echo "$string" "${#string}"
OUTPUT
* * * * * * 30
* * * * * * 30
Parece ok, certo? Bem, vamos alterar o ambiente novamente.
touch file1 file2 file3 file4 file5
echo $string ${#string}
echo "$string" "${#string}"
OUTPUT
file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 30
* * * * * * 30
Woah.
Por padrão, o shell expandirá os globs de nome de arquivo se ele puder combiná-los. Isso ocorre após expansão do parâmetro e divisão do campo em sua ordem de análise e, portanto, qualquer sequência não citada é vulnerável dessa maneira. Você pode alternar esse comportamento com set -f
, se desejar, mas qualquer shell compatível com POSIX sempre será glob por padrão.
Este é o tipo de coisa que você está enfrentando quando você deixa cair as cotações em expansões para atender às suas preferências de indentação. E mesmo assim, em todos os casos, independentemente do seu comportamento de expansão, o valor real para $string
é sempre o que quer que tenha sido quando você o atribuiu pela última vez. Então, vamos voltar para a primeira coisa.
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
echo "$var" "${#var}"
OUTPUT
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like. 70
Acredito que esta é uma maneira muito mais simples de adaptar a sintaxe do shell às suas preferências de recuo. O que estou fazendo acima é atribuir cada string individual a um parâmetro posicional - que pode ser referenciado por um número como $1
ou ${33}
- e então atribuir seus valores concatenados a $var
usando o parâmetro especial shell $*
.
Essa abordagem não é imune a $IFS
, mesmo assim. Ainda assim, considero sua relação com $IFS
um benefício adicional a esse respeito. Considere:
IFS=\ ;space_split="$*"
IFS=/; slash_split="$*";IFS='
';new_line_split="$*"
echo "$space_split"
echo "$slash_split"
echo "$new_line_split"
OUTPUT
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like.
Arg 1: Line 1./Arg 2: Line 2./and so on for/as long as you might like.
Arg 1: Line 1.
Arg 2: Line 2.
and so on for
as long as you might like.
Como você pode ver, $*
concatena cada argumento em "$@"
no primeiro byte em $IFS
. Portanto, salvar seu valor enquanto $IFS
é atribuído de maneira diferente obtém diferentes delimitadores de campo para cada valor salvo. O que você vê acima é o valor literal de cada variável, a propósito. Se você não queria nenhum delimitador você faria:
IFS=;delimitless="$*"
echo "$delimitless" "${#delimitless}"
OUTPUT
Arg 1: Line 1.Arg 2: Line 2.and so on foras long as you might like. 67