좋아, 일반적인 해결책. 다음 bash 함수에는 2k
인수 가 필요합니다 . 각 쌍은 자리 표시 자와 교체로 구성됩니다. 문자열을 적절하게 인용하여 함수에 전달하는 것은 사용자의 몫입니다. 인수 수가 홀수이면 암시적인 빈 인수가 추가되어 마지막 자리 표시 자의 발생을 효과적으로 삭제합니다.
자리 표시 자나 대체물에는 NUL 문자가 포함될 수 없지만 필요한 경우 \
와 같은 표준 C 이스케이프를 사용할 수 있습니다 (따라서 원하는 경우을 작성 해야 함 ).\0
NUL
\\
\
posix와 유사한 시스템 (lex 및 cc)에 있어야하는 표준 빌드 도구가 필요합니다.
replaceholder() {
local dir=$(mktemp -d)
( cd "$dir"
{ printf %s\\n "%option 8bit noyywrap nounput" "%%"
printf '"%s" {fputs("%s", yyout);}\n' "${@//\"/\\\"}"
printf %s\\n "%%" "int main(int argc, char** argv) { return yylex(); }"
} | lex && cc lex.yy.c
) && "$dir"/a.out
rm -fR "$dir"
}
\
인수에서 필요한 경우 이미 이스케이프 된 것으로 가정 하지만 큰 따옴표가 있으면 이스케이프해야합니다. 그것이 두 번째 printf에 대한 두 번째 주장이하는 것입니다. lex
기본 동작은 이므로 ECHO
걱정할 필요가 없습니다.
예제 실행 (회의론자의 타이밍과 함께; 싸구려 상품 노트북 일 뿐임) :
$ time echo AB | replaceholder A B B A
BA
real 0m0.128s
user 0m0.106s
sys 0m0.042s
$ time printf %s\\n AB{0000..9999} | replaceholder A B B A > /dev/null
real 0m0.118s
user 0m0.117s
sys 0m0.043s
더 큰 입력의 경우에 최적화 플래그를 제공하는 것이 유용 할 수 있으며 cc
현재 Posix 호환성을 위해 사용하는 것이 좋습니다 c99
. 더욱 야심 찬 구현은 생성 된 실행 파일을 매번 생성하는 대신 캐시하려고 시도 할 수 있지만 생성 비용이 정확하게 들지는 않습니다.
편집하다
tcc 가 있으면 임시 디렉토리를 작성하는 번거 로움을 피하고 일반적인 크기의 입력에 도움이되는 빠른 컴파일 시간을 즐길 수 있습니다.
treplaceholder () {
tcc -run <(
{
printf %s\\n "%option 8bit noyywrap nounput" "%%"
printf '"%s" {fputs("%s", yyout);}\n' "${@//\"/\\\"}"
printf %s\\n "%%" "int main(int argc, char** argv) { return yylex(); }"
} | lex -t)
}
$ time printf %s\\n AB{0000..9999} | treplaceholder A B B A > /dev/null
real 0m0.039s
user 0m0.041s
sys 0m0.031s
tr AB BA
.