Como converter uma string tracejada em espaços e limites?

1

Dada a string foo-bar , o que é uma boa maneira de convertê-la em Foo Bar ?

Usando o Bash, OSX.

    
por B Seven 09.12.2014 / 01:16

6 respostas

2

Comece alterando traços para espaços, como: sed 's/-/ /g'

Em maiúsculas a primeira letra é já solucionada (suba para cima; ou apenas marque esta questão como duplicata daquela).

Em seguida, combine-os: sed -e 's/-/ /g' -e 's/\b\(.\)/\u/g'

$ echo "foo-bar-baz-nonce" | sed -e 's/-/ /g' -e 's/\b\(.\)/\u/g'
Foo Bar Baz Nonce
$ 
    
por 09.12.2014 / 02:03
2

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.

    
por 09.12.2014 / 06:20
1

Etapa 1: Substitua o - por um espaço

Para isso, você pode usar o comando tr da seguinte forma:

tr "-" " "

Passo 2: Faça a primeira letra de cada palavra em maiúscula

Para isso, você pode encontrar o limite da palavra usando \b e fazer capital de letras imediato. O . representa a letra imediata após o limite da palavra \b , \U torna capital e & manterá todas as outras letras nas letras como eram.

sed -e 's/\b./\U&/g'

Verifique:

echo "foo-bar-foo-bar" | tr "-" " " | sed -e 's/\b./\U&/g'
Foo Bar Foo Bar
    
por 09.12.2014 / 05:09
1

Uma solução que usa , não restrita a apenas 'foo-bar '

$ cat file
aaa-zzz-eee-rrr
foo-bar

código

$ perl -ne 'print join " ", map { ucfirst } split /-/' file
Aaa Zzz Eee Rrr
Foo Bar

Outra solução usando o bash puro

while IFS='-' read -r -a words; do
    printf '%s\n' "${words[@]^}" | paste -sd ' '
done < file

Saída:

Aaa Zzz Eee Rrr 
Foo Bar
    
por 09.12.2014 / 01:25
0

Se essa string fizer parte de um arquivo ou de uma saída:

sed 's/foo-bar/Foo Bar/g' file

Supondo que não haja caracteres "estranhos" na string ( / , \ , & ):

string="foo-bar"
set -- $(echo "${string//-/ }")
replstr="$(for word in $*; do echo -n "${word^} "; done)"
replstr="${replstr% }"
sed "s/${string}/${replstr}/g' file
    
por 09.12.2014 / 01:22
0

em bash

v=foo-bar && v=$(IFS=- read -ra x <<<"$v"; printf '%s' "${x[*]^}") && printf '%s\n' "$v"
Foo Bar

Em python

v=foo-bar python -c 'import os, string
print string.capwords(" ".join(os.environ["v"].split("-")))
'
Foo Bar
    
por 10.12.2014 / 17:11

Tags