$SOME_TEXT_HERE$
このような値を次のような値に置き換えたいと思います。@some.text.here@
つまり:
- テキストを小文字に変更
$
使用。 。 。交換@
- 下線をドットに置き換える
最初の文字列には関係のないテキストがいくつかあります。ドルで区切られたテキストはいくらでも変更できます。ドルで区切られたテキストは、下線で区切られた1つ以上の大文字で構成できます。
ステップ1と2を行う方法を知っています。ステップ3をドル記号の中にあるものに制限する方法が気になります。
いいですね。例は次のとおりです。
から:
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
到着する:
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
私はこれをしました:
echo 'Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$ ' |sed -e 's/\$\([A-Z]\+_\?\)\+\$/\L&/g' -e's/\$\(\([a-z]\+_\?\)\+\)\$/@\1@/g'
これは作る:
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing_elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et_dolore_magna_aliqua@
@シンボル内のすべての単語を取得するために一致するグループの結果を繰り返す方法がわかりません。常に最後に一致する結果が得られます。
答え1
パールの使用:
$ cat file
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
$ perl -pe 's/\$([[:upper:]_]+)\$/"@" . lc $1 =~ tr[_][.]r . "@"/eg' file
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
ここで使用されるPerl式は次のとおりです。
s/\$([[:upper:]_]+)\$/"@" . lc $1 =~ tr[_][.]r . "@"/eg
これは、最初の文字$
、1つ以上の大文字、または下線、他の文字で$
構成される部分文字列に適用される代替です。
$1
代替パターンは、演算子を使用してパターン()の角かっこグループと一致する部分文字列の下線をすべてドットに変更し、結果を小文字にtr
変更するPerl式ですlc
。次に、@
結果の前後に文字を追加します。
これは、Perlが代替テキストを単純なテキストではなくPerl式として扱うことを可能にする式/e
フラグです。s///
すべての一致に対して置換を繰り返すには、このフラグを使用します/g
。
答え2
$string
入力がシェルの変数に保存されたら、次のことがzsh
できます。
set -o extendedglob
string=${string//(#b)\$([A-Z]##(_[A-Z]##)#)\$/@${(L)match[1]//_/.}@}
perl
同じ
string=$(
printf '%s\n' "$string" | perl -pe '
s{\$[A-Z]+(_[A-Z]+)*\$}{lc$& =~ y/_$/.@/r}ge'
)
または:
string=$(
printf '%s\n' "$string" | perl -pe '
s{\$[A-Z]+(_[A-Z]+)*\$}{$& =~ y/A-Z_$/a-z.@/r}ge'
)
違いは、ロケールによってperl
バイトレベル(ASCIIベースのシステムではASCIIエンコードが必要)とzsh
文字レベル(文字でデコードできない場合はバイトに置き換え)で機能することです。エンコーディングを設定します。改行文字で終わっても$string
動作が異なります。これは、コマンド置換によってその文字が削除されるためです。
答え3
GNUの使用sed
:(必要に応じてsed
)
$ sed -E 's/\$([A-Z]+([A-Z]*_)*[A-Z]+)\$/@\L\1@/g;s/@([a-z]+)_/@\1./g;s/_([a-z]+)@/\.\1@/g; :X s/(\.[a-z]+)_/\1\./g; tX'
出力:
$ echo 'Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$' | sed -E 's/\$([A-Z]+([A-Z]*_)*[A-Z]+)\$/@\L\1@/g;s/@([a-z]+)_/@\1./g;s/_([a-z]+)@/\.\1@/g; :X s/(\.[a-z]+)_/\1\./g; tX'
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
答え4
もう少し短いGNUsed
sed -E "s/\\\$([A-Z_]+)\\\$/@\L\1@/g; :X s/(@[a-z.]+)_/\1./; tX" file
これが@
ソースで自然に発生するのではなく、$
最初にのみ発生すると仮定します。[A-Z_]
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
これはあなたの例ではうまくいきますが、代わりに$BLAH_BLAH$blah_
-> を使用すると失敗します。@blah.blah@blah.
@blah.blah@blah_
編集するRe@Quasimodoコメント+
- >*
セカンドsed
sed -E "s/\\\$([A-Z_]+)\\\$/@\L\1@/g; :X s/(@[a-z.]*)_/\1./; tX" file
Lorem $_IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
Lorem @.ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@