sed - 如何将每个第三个单词大写?

sed - 如何将每个第三个单词大写?

鉴于:

main_east_library
main_west_roof
main_north_roof
minor_south_roof

我如何使用sed(具体来说,不是awktr等)来创建:

main_east_Library
main_west_Roof
main_north_Roof
minor_south_Roof

就像是:

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

虽然这给出了:

sed: -e expression #1, char 16: Invalid back reference

答案1

使用 GNU sed

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

将每行的第三个字母序列大写。

大写每一个每行第三个字母序列:

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

将每三个字母序列大写在整个输入中,与 GNU awk

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

或者与perl

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

虽然[[:alpha:]]字符类在某些系统上可能有点随机(例如在 GNU 系统上,包括许多数字,但不包括阿拉伯数字 (0123456789)),但 Perl 的字符类\p{...}基于 Unicode 字符属性。因此,这些\p{alpha}将包括所有字母表中的字母以及非字母字母字符。

它不包括组合变音符号,但这意味着类似的单词Stéphane将被视为两个单独的单词。

所以你可能想要:

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

尽管这最终可能会包括太多。

另请注意,与 GNU 相反sed,Perl会正确地将诸如(where是 1 个连字字符)\u之类的单词转换为(2 个字符和)。fiddleFiddleFi

答案2

珀尔

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

它计算 2 个以下划线结尾的字符序列,然后将下一个字符大写。

答案3

另一个 GNU sed

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

这假设该行始终以单词开头。

相关内容