sed - jak używać wielkich liter co 3 słowa?

9

Dany:

main_east_library
main_west_roof
main_north_roof
minor_south_roof

W jaki sposób można stosować sed(w szczególności, nie awk, tritp), aby utworzyć:

main_east_Library
main_west_Roof
main_north_Roof
minor_south_Roof

Coś jak:

$ echo "main_west_library
main_west_roof
main_north_roof
minor_south_roof" | sed 's_\3_upcase(\3)_' 

Chociaż daje to:

sed: -e expression #1, char 16: Invalid back reference
Michael Durrant
źródło
1
bez awk lub tr twój sed nie powiedzie się, jeśli spróbujesz na starszym systemie lub po prostu innym systemie. Niektóre wyrażenia w odpowiedziach to rozszerzenia GNU!
ikrabbe

Odpowiedzi:

11

Z GNU sed:

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

Dodałaby trzecią sekwencję liter z każdej linii.

Aby wykorzystać każdą trzecią sekwencję liter w każdym wierszu:

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

Aby używać wielkich liter co trzeci ciąg liter w całym danych wejściowych , w GNU awk:

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

Lub z perl:

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

Podczas gdy [[:alpha:]]klasa znaków może być nieco losowa w niektórych systemach (na przykład w systemach GNU, które zawierają wiele cyfr z wyłączeniem arabskich (0123456789)), Perl \p{...}opiera się na właściwościach znaków Unicode. \p{alpha}Będą więc zawierać litery wszystkich alfabetów, a także nieliterowe znaki alfabetu.

Nie będzie jednak obejmował łączenia znaków diakrytycznych, co oznacza, że ​​podobne słowa Stéphanebędą uważane za dwa osobne słowa.

Zamiast tego możesz chcieć:

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

Chociaż może to skończyć, w tym zbyt wielu.

Zauważ też, że w przeciwieństwie do GNU sed, Perl \upoprawnie przekształci słowa takie jak fiddle(gdzie jest jeden znak ligatury) na Fiddle(2 znaki Fi i).

Stéphane Chazelas
źródło
3

perl

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

Liczy 2 sekwencje znaków kończących się znakiem podkreślenia, a następnie wielkie litery następnego znaku.

Glenn Jackman
źródło
2

Kolejny GNU sed:

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

Zakłada się, że linia zawsze zaczyna się od słowa.

Cuonglm
źródło