Isso é feito em Perl:
echo 11-14,17,20 | perl -pe 's/(\d+)-(\d+)/join(",",$1..$2)/eg'
Saída:
11,12,13,14,17,20
Qual é a melhor abordagem para converter a string contendo o intervalo de números em números? Esse formato é usado, por exemplo, na definição do intervalo de páginas a serem impressas. Eu defino, quero imprimir estas páginas "11-14,17,20" . Agora preciso escrever o script bash que mudará essa string para a matriz de números: 11, 12, 13, 14, 17, 20
Ele deve ser capaz de trabalhar com strings que contenham números (mesmo com mais dígitos) e com ',' e '-'.
Aqui está uma solução usando awk
:
#!/bin/bash
pages="11-14,17,20"
echo $pages | awk 'BEGIN { RS=","; FS="-"; ORS="" }
NR > 1 { print "," }
NF > 1 { for (i=$1; i<$2; ++i) { print i "," } print $2; next }
{ print $1 }'
Isso resulta na seguinte saída:
11,12,13,14,17,20
Apenas bash:
expand_ranges() {
local IFS=,
set -- $1
for range; do
case $range in
*-*) for (( i=${range%-*}; i<=${range#*-}; i++ )); do echo $i; done ;;
*) echo $range ;;
esac
done
}
numbers=( $(expand_ranges 11-14,17,20) )
Para a saída solicitada: IFS=,; echo ${numbers[*]}
Se você tem jot
do seu sistema
Exemplo de uso de jot e sed é (não se esqueça do caracter newline na string de substituição!):
$echo 1-2,3,6-9| sed 's/,/\
/g'|sed -E '/-/s/([0-9]+)-([0-9]+)/- /g;s/^([0-9]+)$/- /g'| xargs -L 1 jot | rs -t -C,
1,2,3,6,7,8,9
Se você digitar echo jot
em vez de "jot" (e remover rs
call), deverá ver a seguinte saída:
jot - 1 2
jot - 3 3
jot - 6 9
Esta é uma maneira meio lisp de fazer as coisas (exceto pelo fato de que bash não gosta de listas preguiçosas, então nós temos que definir um limite superior no número máximo de páginas; aqui eu escolhi 10000)
pages="11-14,17,20"; for ((i=1;i<10000;i++)); do echo -n $i, ; done | cut -d , -f $pages
Com as páginas, você especifica o intervalo de páginas como na outra postagem. O loop for gera uma lista de números de páginas. Desses, o comando cut seleciona os que você quer.
Tags bash string bash-scripting