รูปแบบทดแทนภายในไฟล์ที่มีเนื้อหาของไฟล์อื่น


20

ฉันมีไฟล์ข้อความ ( devel.xml)

ฉันเพิ่มคำ REPLACETHIS ลงไปเพื่อแทนที่สตริงนี้ด้วยเนื้อหาภายในไฟล์อื่น ( temp.txt)

สิ่งที่ฉันมีอยู่ใกล้ที่สุดคือ:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

สิ่งนี้แทรกเนื้อหาหลังสตริงและจากนั้นลบสตริงในภายหลัง

นี่เป็นวิธีที่ดีที่สุดที่จะทำ?


มันจะต้องใจเย็น ๆ ไหม? ขึ้นอยู่กับจำนวนข้อความใน temp.txt ฉันอาจก้าวไปสู่การแก้ปัญหา perl
user17591

คำตอบ:


34

สิ่งที่คุณทำคือการลบSUBSTITUTETHISที่ใดก็ตามที่ปรากฏในไฟล์ (แต่ไม่ใช่ส่วนที่เหลือของบรรทัดที่ปรากฏ) และแทรกเนื้อหาtemp.TXTด้านล่างของบรรทัดนั้น หากSUBSTITUTETHISปรากฏขึ้นหลายครั้งในหนึ่งบรรทัดจะมีเพียงการเกิดขึ้นครั้งแรกเท่านั้นและtemp.TXTจะมีการเพิ่มเพียงหนึ่งสำเนาเท่านั้น

หากคุณต้องการแทนที่ทั้งบรรทัดเมื่อSUBSTITUTETHISปรากฏขึ้นให้ใช้dคำสั่ง เนื่องจากคุณต้องเรียกใช้ทั้งสองrและdเมื่อมีการแข่งขันให้ใส่พวกเขาในกลุ่มที่ค้ำยัน

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

การนำไปปฏิบัติบางอย่างทำให้คุณสามารถใช้เซมิโคลอนเพื่อแยกคำสั่งและละเว้นตัวคั่นโดยรอบการจัดฟัน แต่คุณยังต้องขึ้นบรรทัดใหม่เพื่อยุติการโต้แย้งrคำสั่ง:

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

หากคุณต้องการแทนที่SUBSTITUTETHISด้วยเนื้อหาของไฟล์ แต่เก็บสิ่งที่มาก่อนและหลังในบรรทัดมันมีความซับซ้อนมากขึ้น วิธีที่ง่ายที่สุดคือการรวมเนื้อหาของไฟล์ในคำสั่ง sed; โปรดทราบว่าคุณจะต้องอ้างเนื้อหาอย่างถูกต้อง

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' | tr -d '\n')/g" -i devel.txt

หรือใช้ Perl นี่สั้น แต่วิ่งcatหนึ่งครั้งสำหรับการทดแทนแต่ละครั้ง:

perl -pe 's/SUBSTITUTETHIS/`cat temp.TXT`/ge' -i devel.txt

หากต้องการอ่านไฟล์หนึ่งครั้งเมื่อสคริปต์เริ่มต้นและหลีกเลี่ยงขึ้นอยู่กับคำสั่งเชลล์:

perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(นำเสนอในสองบรรทัดเพื่อให้อ่านได้ แต่คุณสามารถละเว้นการขึ้นบรรทัดใหม่ได้) หากชื่อไฟล์เป็นตัวแปรเพื่อหลีกเลี่ยงปัญหาในการอ้างอิงผ่านไปยังสคริปต์ผ่านตัวแปรสภาพแวดล้อม:

replacement_file=temp.TXT perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

ฉันจะเปลี่ยนคำสั่ง perl เพื่อที่cat temp.txtฉันจะได้ทำแทนได้cat ${variable}อย่างไร
Maria Ines Parnisari

@MariaInesParnisari ฉันทำผิดกับการจัดรูปแบบความคิดเห็น ดูคำตอบของฉันด้วยโซลูชันที่แตกต่างและแข็งแกร่งกว่าเล็กน้อย
Gilles 'หยุดความชั่วร้าย'

เนื่องจาก File :: Slurp ไม่ได้ติดตั้งไว้ตลอดเวลาทางเลือกอื่นคือใช้-0777สวิตช์เพื่อ slurp ในไฟล์ทั้งหมดและแบบปกติopen:perl -0777 -pe 'BEGIN {open F, q(temp.TXT); $r=<F>; chomp($r)} s/SUBSTITUTETHIS/$r/ge' -i devel.txt
mivk

วิธีการห่อr temp.TXTด้วยข้อความเช่น "BEGIN temp.TXT", "END temp.TXX"
kyb

ฉันพบวิธีแก้ปัญหาสำหรับคำถามของฉัน ใช้aคำสั่ง (เพิ่ม) grymoire.com/Unix/Sed.html#uh-36
kyb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.