sed - como capitalizar toda terceira palavra?

9

Dado:

main_east_library
main_west_roof
main_north_roof
minor_south_roof

Como posso usar sed (especificamente, não awk , tr , etc.) para criar:

main_east_Library
main_west_Roof
main_north_Roof
minor_south_Roof

Algo como:

$ echo "main_west_library
main_west_roof
main_north_roof
minor_south_roof" | sed 's__upcase()_' 

Embora isso dê:

sed: -e expression #1, char 16: Invalid back reference
    
por Michael Durrant 23.06.2015 / 17:55

3 respostas

11

Com o GNU sed :

sed -E 's/[[:alpha:]]+/\u&/3'

Seria capitalizar a terceira seqüência de letras de cada linha.

Para capitalizar cada terceira seqüência de letras em cada linha:

sed -E 's/(([[:alpha:]]+[^[:alpha:]]+){2})([[:alpha:]]+)/\u/g'

Para capitalizar cada terceira seqüência de letras em toda a entrada , com o GNU awk :

awk -v RS='[^[:alpha:]]+' -v ORS= '
   NR % 3 == 0 {$0=toupper(substr($0,1,1)) substr($0,2)}
   {print $0 RT}'

Ou com perl :

perl -Mopen=locale -pe 's/\p{alpha}+/++$n % 3 == 0 ? "\u$&" : "$&"/ge'

Enquanto a classe de caractere [[:alpha:]] pode ser um pouco aleatória em alguns sistemas (por exemplo, em sistemas GNU, isso inclui muitos numerais com a exclusão dos arábicos (0123456789)), \p{...} de Perl é baseado em caracteres Unicode propriedades. Então, esses \p{alpha} incluirão letras em todos os alfabetos e também caracteres alfabéticos não alfabéticos.

Não incluirá combinação de diacríticos, o que significa que palavras como Stéphane seriam consideradas como duas palavras separadas.

Então você pode querer:

perl -Mopen=locale -pe 's/[\p{alpha}\p{mark}]+/++$n % 3 == 0 ? "\u$&" : "$&"/ge'

Embora isso possa acabar, incluindo muitos.

Observe também que, contrariamente ao GNU sed , \u do Perl irá transformar corretamente palavras como fiddle (onde é um caractere de ligadura) para Fiddle (2 caracteres F e i ) .

    
por 23.06.2015 / 18:01
3

perl

perl -pe 's/(?:.*?_){2}\K./\u$&/'

Conta 2 sequências de caracteres terminados em sublinhado, depois maiúscula o próximo caracter.

    
por 23.06.2015 / 18:42
2

Outro GNU sed :

sed -E 's/([^[:alpha:]])([[:alpha:]])/\u/2'

Isso pressupõe que a linha sempre comece com uma palavra.

    
por 23.06.2015 / 18:08

Tags