따라서 내 파일의 텍스트 형식은 다음과 같습니다.
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
유니코드 설정(이 훌륭한 답변에 감사드립니다.유니코드 문자의 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
s 표현식은 작은따옴표 대신 큰따옴표로 묶여 있으므로 기호 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} бац",