鉴于:
main_east_library
main_west_roof
main_north_roof
minor_south_roof
我如何使用sed
(具体来说,不是awk
、tr
等)来创建:
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 个字符和)。fiddle
fi
Fiddle
F
i
答案2
珀尔
perl -pe 's/(?:.*?_){2}\K./\u$&/'
它计算 2 个以下划线结尾的字符序列,然后将下一个字符大写。
答案3
另一个 GNU sed
:
sed -E 's/([^[:alpha:]])([[:alpha:]])/\1\u\2/2'
这假设该行始终以单词开头。