ตกลงวิธีแก้ปัญหาทั่วไป ฟังก์ชัน bash ต่อไปนี้ต้องการ2k
อาร์กิวเมนต์ แต่ละคู่ประกอบด้วยตัวยึดตำแหน่งและการแทนที่ มันขึ้นอยู่กับคุณที่จะพูดสตริงอย่างเหมาะสมเพื่อส่งผ่านเข้าไปในฟังก์ชัน หากจำนวนอาร์กิวเมนต์เป็นจำนวนคี่จะมีการเพิ่มอาร์กิวเมนต์ว่างโดยนัยซึ่งจะลบการเกิดขึ้นของตัวยึดตำแหน่งสุดท้ายอย่างมีประสิทธิภาพ
ตัวยึดตำแหน่งหรือการแทนที่อาจไม่มีอักขระ NUL แต่คุณอาจใช้ C \
-escapes มาตรฐานเช่น\0
ถ้าคุณต้องการNUL
s (และดังนั้นคุณต้องเขียน\\
ถ้าคุณต้องการ a \
)
มันต้องใช้เครื่องมือสร้างมาตรฐานซึ่งควรจะปรากฏในระบบเหมือน posix (เล็กและซีซี)
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
เราไม่ต้องกังวลเกี่ยวกับมัน
ตัวอย่างการรัน (ด้วยการกำหนดเวลาสำหรับผู้สงสัยมันเป็นเพียงแล็ปท็อปสินค้าราคาถูก o):
$ 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
สำหรับนี้คุณสามารถใช้