Para a divisão em um shell POSIX, você pode fazer:
set -f; IFS=-; set -- $1; IFS=' '
Lá, agora todos os seus traços são espaços e você pode ter a string inteira em "$*"
ou então cada espaço - string separada por traço anterior em $1
$2
$3
... ( a contagem total está disponível para você em "$#"
) ou você pode obtê-los como uma lista de argumentos expansível em "$@"
.
Agora, para a conversão do caso, você pode fazer:
IFS='
'; for c in $(printf %.1s "$@" | dd cbs=1 conv=unblock,ucase)
do set -- "$@" "$c${1#[!"$IFS"]}"; shift; done
Aqui está a coisa toda pelo exemplo:
set -f -- aaa-zzz-eee-rrr-foo-bar
IFS=-; set -- $1; IFS='
'; for c in $(printf %.1s "$@" | dd cbs=1 conv=unblock,ucase)
do set -- "$@" "$c${1#?}"
shift; done; printf %s\n "$@"
quais impressões:
Aaa
Zzz
Eee
Rrr
Foo
Bar
... que não é separado por espaços, eu sei - usei "$@"
. Ele é separado por espaço em "$*"
porque eu defino o primeiro byte do$IFS
para o espaço - o delimitador é definível dessa forma. Por exemplo:
IFS=k; printf %s\n "$*"; IFS=' '; printf %s\n "$*"
... que imprime ...
AaakZzzkEeekRrrkFookBar
Aaa Zzz Eee Rrr Foo Bar
Você pode salvá-lo a qualquer momento, é claro:
IFS=-; dashes="$*"; IFS=' '; spaces="$*"; IFS=; empty="$*"
printf %s\n "$dashes" "$spaces" "$empty"
... que imprime:
Aaa-Zzz-Eee-Rrr-Foo-Bar
Aaa Zzz Eee Rrr Foo Bar
AaaZzzEeeRrrFooBar
Este é um assunto mais complexo, mas pode ser usado com grande efeito nessas áreas. No entanto, é importante proteger a integridade dos dados - use set -f
ao dividir o shell para evitar a geração de nome de arquivo em [?*
e as expansões de cotação que você não pretende dividir.
O comando dd
acima - como deve ser observado - provavelmente só será muito eficaz em uma localidade ASCII. Em outros, você provavelmente deve procurar recode
ou iconv
ou similar.