2番目のパターンの前に1つのパターンを置き換える場合 - 2つのパターンの間に文字列を保持します。

2番目のパターンの前に1つのパターンを置き換える場合 - 2つのパターンの間に文字列を保持します。

これは私のコードです。

printf '%s' '{$aaa} \\{$bbb} \{$ccc}  {$ddd' | sed -r -e 's/(^|[^\\])\{\$/\1\$\{/g' -e 's/\\\\\{\$/\\\\\$\{/g'

結果:

${aaa} \\${bbb} \{$ccc} ${ddd

{$ddd閉じ括弧で終わらないため、置き換えるべきでない最後のパターンを除いて、結果は正常です}

sedを使用してこれを行うにはどうすればよいですか?

また、2つの実際の表現を組み合わせる方法を知っていれば大歓迎です(私にとってはそれほど重要ではありません)。

編集:括弧も($foo)次のことを行います。$(foo)

ベストアンサー1

最初の作業から始めて閉じるまでのみ変更を行います{}

printf '%s' '{$aaa} \\{$bbb} \{$ccc}  {$ddd' | sed 's/{$\([^}]*\)}/${\1}/g'

つまり、{$終わりから終わりまでのすべての内容} が に配置されるので、\(\)代替文字列でこれを逆参照できます\1。出力:

${aaa} \\${bbb} \${ccc}  {$ddd

ここでバックスラッシュエスケープについて説明します。あなたのソリューションは\{$aaa}(触れないでください)と\\{$aaa}(交換)には効果的ですが、何ですか\\\{$aaa}?望ましくない変更が行われます。

したがって、最初にすべての二重バックスラッシュを削除することをお勧めします。たとえば、文字列の一部になることができない文字の組み合わせに置き換えて、#1最終的に再変更します。これにより、単一のバックスラッシュにのみ集中できます。

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/#1/g;s/{$\([^}]*\)}/${\1}/g;s/#1/\\\\/g'

最後に、これを削除するには、最後に次のように\{変更して再交換することができます。#2

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/#1/g;s/\\{/#2/g;s/{$\([^}]*\)}/${\1}/g;s/#2/\\{/g;s/#1/\\\\/g'

結果:${aaa} \\${bbb} \{$ccc} \\\{$eee} {$ddd

これはバックスラッシュの数に関係なく機能します。

しかし、#あなたと同じキャラクターを勝手に使えないとしたらどうでしょうか?改行文字は行の一部にできないため、改行文字を使用できます。あなたはGNUを使っているようですので、これを行うことがsedできます。

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/\n1/g;s/\\{/\n2/g;s/{$\([^}]*\)}/${\1}/g;s/\n2/\\{/g;s/\n1/\\\\/g'

POSIXで実行するには、sed次のものが必要です。解決策

おすすめ記事