したがって、私のファイルのテキスト形式は次のようになります。
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 -Mutf8
Unicode設定(この素晴らしい答えに感謝します。Unicode文字のtrシミュレーション?)-F: -lane
:
フィールド区切り文字として使用され、配列@F
に保存されます(参照:https://perldoc.perl.org/perlrun.html#Commandスイッチ他のオプションの場合)$F[-1]
@F
配列の最後のフィールド\{[^{}]+\}(*SKIP)(*F)|[a-z]+
[a-z]+
ここでは、部品は一致する必要がありますが、\{[^{}]+\}
そのまま維持する必要があると言います。$&=~tr|abc|абц|r
一致する部分を音域ge
g
すべての一致を置き換えるための修飾子、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);
}
答え2
滞在を希望する場合sed
:
sed 's/"/"_/;:l
s/_[^{]*/&_/;h
s/.*_\(.*\)_.*/\1/
y/abc/абц/;G
s/\(.*\)\n\(.*\)_.*_\([^}]*}\)\{0,1\}/\2\1\3_/
/_$/!bl
s/_//'
処理中に下線をマーカーとして使用します。下線がファイルの一部である可能性がある場合は、別の区切り文字を使用してください。
アイデアは文字列の一部を表示し、スペースを保存するためにコピーを保存し、表示外のすべてを削除し、変換を実行し、コピーを再インポートし、変換された部分に文字列を形成し、下線を前に移動しますすることです。その部分がある場合は、{}
その部分をスキップしてください。
興味があれば、より詳細な説明を提供してください。
答え3
sed -rf <(echo ':l'; printf 's/("| [^{]*)%s/\\1%s/g\n' a а b б c ц; echo 'tl') input.txt
または、より簡潔ですが、エラーが発生しやすいです。sed
■式は一重引用符ではなく二重引用符で囲まれているため、記号bash
などの特殊文字は$
エスケープする必要があります。
sed -r ":l; $(printf 's/("| [^{]*)%s/\\1%s/g;' a а b б c ц) tl" input.txt
説明する(最初のコマンドが実行されます)
sed -f script-file
- 実行する命令にスクリプトファイルの内容を追加します。
<()
- プロセスの置き換え。これにより、コマンド出力をファイルとして表示し、ファイルを必要なコマンドに渡すことができます。
echo ':l'; printf 's/("| [^{]*)%s/\\1%s/g\n' a а b б c ц; echo 'tl'
- 次のコマンド順に切り替わりますsed
。
:l
s/("| [^{]*)a/\1а/g
s/("| [^{]*)b/\1б/g
s/("| [^{]*)c/\1ц/g
tl
テスト:
入力する
abcTestString : "abc {bcb} bbc",
abcTestString : "bbc {acb} bbc {bcb}",
abcTestString : "acc {cab} {ccb} bbc",
abcTestString : "cbc {ccb} bac {aca} bac",
出力
abcTestString : "абц {bcb} ббц",
abcTestString : "ббц {acb} ббц {bcb}",
abcTestString : "ацц {cab} {ccb} ббц",
abcTestString : "цбц {ccb} бац {aca} бац",