] 後ろの最初の文字を大文字に変更します。

] 後ろの最初の文字を大文字に変更します。

次の何千もの行を含むCSVファイルがあります。

bla bla blab [FR] john is bla bla
bla [US] blue house in Chicago...
[ES] accessing the safe... bla bla

間の要素を確認してください[ ]。これらの要素の後には、常にスペースと新しいフレーズの先頭が続きます。ファイルが次のように見えるように、スペースの後ろの最初の文字を大文字に変換したいと思います。

bla bla blab [FR] John is bla bla
bla [US] Blue house in Chicago...
[ES] Accessing the safe... bla bla

sed、awk、または他の手段を使用して端末でこれをどのように実行しますか?

解決策を説明してください。理解して学びたいです。

ありがとうございます。

答え1

POSIXlyでは、次のことができます。

awk -F '] ' '{
  out = $1
  for (i = 2; i <= NF; i++)
    out = out FS toupper(substr($i, 1, 1)) substr($i, 2)
  print out}' < infile

または:

awk '
  BEGIN {FS = OFS = "] "}
  {
    for (i = 2; i <= NF; i++)
      $i = toupper(substr($i, 1, 1)) substr($i, 2)
    print
  }' < infile

これはフィールド区切り文字"] "として定義され、F各フィールドの最初の文字(ndから始まりフィールド番号まで)を変換してからSフィールドを再結合します。2NFNFto upper

(ただし、FreeBSD awk(およびmacOS)を含む一部の実装はまだ国際化されていないため、事前設定された形式(U + 00E9)に変更(またはifに変更)することはできません。mawkawk[GR] π[GR] Π[FR] éric[FR] Éricé

答え2

GNUシステムでは、次のものを使用できますsed

sed 's/] ./\U&/g' <infile

Sトレメ編集するイトールS代替/何を交換するのか/使用。 。 。交換/Gグローバル '<入力ファイル

ここ"何を交換するのか"はリテラルで、スペース]文字(.はewlineを除く単一文字と一致しますが、\newline文字がパターンスペースにある場合はewline文字と一致します。フラグが正規表現に追加されない限り、そうでない場合はewline文字と一致します。しません。)\nperls

何を交換するのかisは\U&sedの&「replace-what」部分(表示されている)への逆参照であるため、一致する部分は大文字に置き換えられます。\U\Upper-case\U&


sedGNUでない場合は、sed次のように同じことができますperl

perl -Mopen=locale -pe 's/] ./\U$&/g' < infile

答え3

まず、FSを設定できます。-v FS="[]][[:space:]]+"つまり、次のように[]]設定する[[:space:]]+と変更されたフィールドが得られます。

$ awk -v FS="[]][[:space:]]+" '{print  $2}' file
john is bla bla
blue house in Chicago...
accessing the safe... bla bla

ここでは、「空白の後ろの最初の文字を大文字に変換」しようとしているので、次のことをテストできます。

awk -v FS="[]][[:space:]]+" '{print toupper(substr($2,1,1))substr($2,2)}'  file

John is bla bla
Blue house in Chicago...
Accessing the safe... bla bla

すべて印刷します。

$ awk -v FS="[]][[:space:]]+" '{print $1, toupper(substr($2,1,1))substr($2,2)}'  file
bla bla blab [FR John is bla bla
bla [US Blue house in Chicago...
[ES Accessing the safe... bla bla

しかし、問題があります。区切り文字がありません。この場合、関数の4番目のパラメータを使用して関数にsplit()挿入できます。FSしたがって、変更と希望の結果を得ることができます。

awk -v FS="[]][[:space:]]+" '                                              
{
split($0, a, FS, seps)
a[i]=$1
a[2]= toupper(substr($2,1,1))substr($2,2)
for (i=1; i<=NF; i++)
printf "%s%s", a[i], seps[i]
print ""
  }
' file
bla bla blab [FR] John is bla bla
bla [US] Blue house in Chicago...
[ES] Accessing the safe... bla bla

コードを書いてくれたEd Mortonに感謝します。https://stackoverflow.com/a/22211988ここで詳細を見ることができます。

関連情報