次の何千もの行を含む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
フィールドを再結合します。2
NF
N
F
to
upper
(ただし、FreeBSD awk
(およびmacOS)を含む一部の実装はまだ国際化されていないため、事前設定された形式(U + 00E9)に変更(またはifに変更)することはできません。mawk
awk
[GR] π
[GR] Π
[FR] éric
[FR] Éric
é
答え2
GNUシステムでは、次のものを使用できますsed
。
sed 's/] ./\U&/g' <infile
Sトレメ編集するイトールS代替/何を交換するのか/使用。 。 。交換/Gグローバル '<入力ファイル
ここ"何を交換するのか"はリテラルで、スペース]
と文字(
.
はewlineを除く単一文字と一致しますが、\n
ewline文字がパターンスペースにある場合はewline文字と一致します。フラグが正規表現に追加されない限り、そうでない場合はewline文字と一致します。しません。)\n
perl
s
」何を交換するのかisは\U&
sedの&
「replace-what」部分(表示されている)への逆参照であるため、一致する部分は大文字に置き換えられます。\U
\Upper-case
\U&
sed
GNUでない場合は、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ここで詳細を見ることができます。