0

私がそのようなものを持っていると仮定します:

echo "bLah BLaH blAH" | sed -r 's/([a-zA-Z ]+)/\L&; s/[a-z]/\u&/g'

「クレイジーケース」文字列を大文字と小文字が混在する(最初の文字は大文字、残りの文字は小文字)にするためのsedの非常に典型的な使用法

ただし、これは常に文字列全体に影響します。たとえば、さまざまなフレーバー ($tracknr - $artist - $title vs. $artist - $tracknr - $title) で「クレイジーな」mp3 ファイル名を解析したい場合、タイトルが外国語である場合があるため、事態はさらに複雑になります。フランス語や大文字と小文字が混在しているように、フランス語やイタリア語では見た目が醜いだけです。そのため、スペース、ダッシュ、スペースなどの区切り文字に到達するまで処理を続行したいと考えています。

したがって、's/.../...' 式を組み合わせて段階的に処理したいと考えています。ただし、次の sed replace 式のソース式として保存されたサブマッチを使用できるようにするために、前の式から部分式を「保存」する方法があれば便利です。

とにかくOOTBで動作すると思うなら、あなたは間違っています。セミコロンの後の 2 番目の式で '\1' 構文を使用して、前の式の部分式を参照することはできません (もちろん、2 番目の式自体で部分式を定義すると機能しますが、この可能性は今は考慮されていません)。私の場合、パーサーには不明であり、エラーが発生します

sed: -e expression #1, char (xx): invalid reference \1 on `s' command's RHS

そのようなことを実行するために実装されたものはありますか?

4

4 に答える 4

2

問題

各単語の最初の文字を大文字にしたいとします。

あなたの質問はあなたの人生を必要以上に困難にします

ホールド スペースにテキストを格納するか、連続式およびネストされた式を使用して、一致するパターンに対して複数の操作を実行できます。行を再処理するための保留スペースを使用して、いくつかの悪ふざけを引き出すことさえできるかもしれません。ただし、ある程度の複雑さを超えると、本当の問題は「言語 X でこれができるかどうか」ではありません。むしろ「これに最適化されている言語は何ですか?」

正規の PCRE エンジンを使用して大量のテキスト変更を行い、複雑なロジックを介して部分式を追跡する場合は、Perl の方が適しています。チューリング完全な言語であれば何でも構いませんが、Perl のバックロニムの 1 つに「Pathologically Eclectic Rubbish Lister」という理由があります。

簡単な GNU sed ソリューション

求めているすべての複雑さは必要ありません。いくつかの基本的な GNU sed 拡張機能は、あなたが望むことを行います。

echo "bLah BLaH blAH" |
sed -r 's/(\b[a-zA-Z ]+\b)/\L&/g; s/\b[a-zA-Z ]/\u&/g'

これにより、各単語の最初の文字を大文字にする目的の出力が生成されます。

何とか何とか何とか

于 2012-06-12T21:38:54.633 に答える
2

@CodeGnomeが正しいと仮定すると、あなたが望むのは

各単語の最初の文字を大文字にしたいとします。

この代替手段を使用できます (これはまだ GNU-ism です。 を参照してください\L \U)。

sed 's;\(.\)\([^ ]*\) \?;\U\1\L\2 ;g'

あなたの例:

$ echo "bLah BLaH blAH" | sed 's;\(.\)\([^ ]*\) \?;\U\1\L\2 ;g'
Blah Blah Blah

GNU-isms (IRC の dualbus のおかげで) を使用して回避するsedことができる以外の他のソリューションを使用することに問題がない場合awk

awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1))tolower(substr($i,2))}}1'

例:

$ echo "bLah BLaH blAH" | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1))tolower(substr($i,2))}}1'
Blah Blah Blah
于 2012-06-12T21:43:10.803 に答える
1

Perlワンライナーアプローチ;)

echo "bLah BLaH blAH" |
    perl -ne '@_ = map { ucfirst } split; print join " ", @_, $/'
BLah BLaH BlAH

それは私が推測するすべてのユニスで機能します=)

私はそれを分解します:

perl         # ?! dunno =)
-n           # assume "while (<>) { ... }" loop around program
-e           # one line of program (several -e's allowed, omit programfile)
@_           # default array name
=            # what you expect
map          # take a list as argument, and perform modification. Return a list
{ ucfirst }  # modification on the list
split        # without argument, takes the current line (we use -n switch)
;            # end of the first instruction
print        # what you expect
join " ", @_ # join a space on the list
$/           # by default, a newline (see perldoc perlvar)
于 2012-06-12T21:55:35.967 に答える
1

または awk で、正規表現のオーバーヘッドなしで:

[ghoti@pc ~]$ echo "bLah BLaH blAH" | awk 'BEGIN{RS=" ";ORS=RS} {print toupper(substr($0,1,1)) tolower(substr($0,2))}'
Blah Blah Blah
于 2012-06-12T22:06:39.597 に答える