sed-3番目の単語をすべて大文字にする方法


9

与えられた:

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
awkまたはtrを使用しない場合、レガシーシステムまたは他のシステムでsedを実行すると失敗します。回答の一部の表現はGNU拡張です。
ikrabbe

回答:


11

GNUの場合sed

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

各行の3番目の文字シーケンスを大文字にします。

活用するために、すべての各行の文字の第3のシーケンスを:

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

GNUを使用して、入力全体で文字の3番目ごとのシーケンスを大文字にするには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は2つの別個の単語と見なされます。

代わりにあなたが望むかもしれません:

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

それは多すぎて終わるかもしれませんが。

また、GNUとは異なりsed、Perl は(合字文字が1つある場合)\uなどの単語を(2文字と)に正しく変換します。fiddleFiddleFi


3

perl

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

アンダースコアで終わる2つの文字シーケンスをカウントし、次の文字を大文字にします。


2

別のGNU sed

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

これは、行が常に単語で始まると想定しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.