Então, se eu tenho uma variável
VAR='10 20 30 40 50 60 70 80 90 100'
e ecoar
echo "$VAR"
10 20 30 40 50 60 70 80 90 100
No entanto, mais abaixo, no script, preciso reverter a ordem dessa variável, para que ela seja exibida como algo como
echo "$VAR" | <code to reverse it>
100 90 80 70 60 50 40 30 20 10
Eu tentei usar rev e literalmente reverteu tudo, então saiu
echo "$VAR" | rev
001 09 08 07 06 05 04 03 02 01
Respostas:
Nos sistemas GNU, o reverso de cat é tac:
fonte
echo $'100 \n90 80 70 60 50 40 30 20 10'
tac -s" " <<< "$VAR "
versão, ainda insere uma linha em branco inicial, adiciona um espaço à direita e omite o caráter de fuga de nova linha (como seprintf '\n%s ' "$reversed_VAR"
em vez de esperarprintf '%s\n' "$reversed_VAR"
)echo $(tac -s" " <<< $VAR)
não possui um espaço à direita porque$(…)
remove novas linhas e espaços à direita se o IFS os possuir. Minha solução será corrigida em breve, obrigado.Para uma lista curta e em uma variável, o próprio shell é a solução mais rápida:
Resultado:
Nota: a operação de divisão em
set -- $var
é segura para a sequência exata usada aqui, mas não será assim se a sequência contiver caracteres curinga (*
,?
ou[]
). Pode ser evitado comset -f
antes da divisão, se necessário. A mesma nota também é válida para as seguintes soluções (exceto onde indicado).Ou, se você deseja definir outra variável com a lista reversa:
Ou usando apenas os parâmetros posicionais.
Ou usando apenas uma variável (que pode ser a própria var):
Nota: Esta solução não é afetada pela globing nem pelo IFS.
fonte
awk
para o resgatecom
perl
, cortesia Como ler um endereço IP ao contrário? compartilhado por @steeldriverOu,
bash
convertendo a string em arrayfonte
Você pode usar recursos do bash, como matrizes, para fazê-lo totalmente em processo:
Essa deve ser a maneira mais rápida de fazer isso, desde que o $ VAR não seja muito grande.
fonte
VAR='+ * ?'
). Useset -o noglob
ouset -f
para consertar isso. De maneira mais geral, é uma boa ideia considerar o valor$IFS
e o estado do globbing ao usar o operador split + glob. Não que faça pouco sentido usar esse operadorrev_a+=( ${a[$i]} )
,rev_a+=( "${a[$i]}" )
faria muito mais sentido.fonte
Use um pouco de magia Python aqui:
A maneira como isso funciona é bastante simples:
"$VAR"
como o segundo parâmetro de linha de comandosys.argv[1]
(o primeiro parâmetro com-c
opção é sempre exatamente isso --c
ele próprio. Observe as aspas"$VAR"
para evitar a divisão da variável em palavras individuais (o que é feito por shell, não por python).split()
método, para dividi-lo em uma lista de strings[::-1]
parte é apenas sintaxe de fatia estendida para reverter a lista" ".join()
e imprimimosMas aqueles que não são grandes fãs de Python, poderíamos
AWK
fazer essencialmente a mesma coisa: dividir e imprimir array ao contrário:fonte
python3 -c 'import sys;print(*reversed(sys.argv[1:]))' $VAR
$IFS
contém os caracteres adequados e sem desativar a parte glob."$VAR"
rendimentopython3 -c 'import sys;print(*reversed(sys.argv[1].split()))' "$VAR"
zsh
:$=VAR
divide$VAR
em$IFS
.(Oa)
ordena a lista resultante na ordem inversa da matriz.print -r --
(como emksh
), o mesmo queecho -E -
(zsh
específico) é uma versão confiável deecho
: imprime seus argumentos como estão separados por espaço, finalizados por nova linha.Se você deseja dividir somente no espaço, e não no
$IFS
conteúdo (espaço, tabulação, nova linha, nul por padrão), atribua espaço$IFS
ou use uma divisão explícita como:Para classificar em ordem numérica inversa:
POSIXly (assim também funcionaria
bash
):printf
Somente com mecanismos embutidos no shell (exceto em alguns shells) (melhor para variáveis com um valor curto):With
awk
(melhor para variáveis grandes, especialmente combash
, mas até o limite do tamanho dos argumentos (ou de um único argumento)):fonte
Ferramentas de software POSIX deselegantes , uma linha:
fonte