sed を使用して文字列の一部を無視します。

sed を使用して文字列の一部を無視します。

したがって、私のファイルのテキスト形式は次のようになります。

untranslatedString : "translated string",

「翻訳された文字列」セクションの文字をキリル文字に置き換える必要があります。私は次のようなものを使用します:

paste <(sed 's/\([^:]\+:\)\([^:]\+\)/\1/' resources.js) <(sed 's/[^:]\+:\([^:]\+\)/\1/;y/abc/абц/' resources.js)

(abc / абц /部分は実際には長く、すべての文字を含みます。これは説明のためです)

問題は、次の行で発生します。

abcTestString : "abc {ccb} bbc",

{}の間のすべての項目は元の状態のままでなければなりません。つまり、文字を交換しないでください。結果は次のとおりです。

abcTestString : "aбц {ccb} ббц",

まさか

abcTestString : "aбц {ццб} ббц",

さらに、各行には複数の{}セクションがあります。

どうすればいいですか?

ベストアンサー1

使えるならperl

$ s='abcTestString : "abc {ccb} bbc",'
$ echo "$s" | perl -Mopen=locale -Mutf8 -F: -lane '
               $F[-1]=~s/\{[^{}]+\}(*SKIP)(*F)|[a-z]+/$&=~tr|abc|абц|r/ge;
               print join ":",@F'
abcTestString : "абц {ccb} ббц",
  • -Mopen=locale -Mutf8Unicode設定(この素晴らしい答えに感謝します。Unicode文字のtrシミュレーション?)
  • -F: -lane:フィールド区切り文字として使用され、配列@Fに保存されます(参照:https://perldoc.perl.org/perlrun.html#Commandスイッチ他のオプションの場合)
  • $F[-1]@F配列の最後のフィールド
  • \{[^{}]+\}(*SKIP)(*F)|[a-z]+[a-z]+ここでは、部品は一致する必要がありますが、\{[^{}]+\}そのまま維持する必要があると言います。
  • $&=~tr|abc|абц|r一致する部分を音域
  • gegすべての一致を置き換えるための修飾子、eセクションでPerlコードの置き換えを許可するための修飾子


コードが大きすぎてコマンドラインで処理できない場合は、プログラムに変更してください。

$ echo "$s" | perl -MO=Deparse -Mopen=locale -Mutf8 -F: -lane '
               $F[-1]=~s/\{[^{}]+\}(*SKIP)(*F)|[a-z]+/$&=~tr|abc|абц|r/ge;
               print join ":",@F'
BEGIN { $/ = "\n"; $\ = "\n"; }
use open (split(/,/, 'locale', 0));
use utf8;
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our @F = split(/:/, $_, 0);
    $F[-1] =~ s[\{[^{}]+\}(*SKIP)(*F)|[a-z]+][use utf8 ();
    $& =~ tr/abc/\x{430}\x{431}\x{446}/r;]eg;
    print join(':', @F);
}

おすすめ記事