แทนที่สตริงด้วยเนื้อหาของไฟล์โดยใช้ sed


23

ฉันมีสองไฟล์ที่แตกต่างกัน:

file1

/home/user1/  
/home/user2/bin  
/home/user1/a/b/c

file2

<TEXT1>
<TEXT2>

ฉันต้องการที่จะเข้ามาแทนที่<TEXT1>ของFile2กับเนื้อหาของFile1sedใช้ ฉันลองคำสั่งนี้ แต่ไม่ได้ผลลัพธ์ที่เหมาะสม:

cat File2|sed "s/<TEXT1>/$(cat File1|sed 's/\//\\\//g'|sed 's/$/\\n/g'|tr -d "\n")/g"

คุณสามารถใช้เครื่องมืออื่นเพื่อแก้ไขปัญหานี้ได้เช่นกัน


โปรดวางข้อความแสดงข้อผิดพลาดนั้นเพื่อให้เราสามารถค้นหาแหล่งที่มา บอกเราsedด้วยว่าคุณกำลังใช้งานระบบใด รหัสคุณทำงานสำหรับฉันกับ sedGNU
จัดการ

ขออภัยไม่ได้รับข้อผิดพลาด ฉันไม่ได้รับผลลัพธ์ที่ต้องการ ผลผลิตก็เหมือน/home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>กัน ไม่ได้รับสายใหม่
chanchal1987

ไม่แน่ใจว่าสิ่งนี้จะนำไปใช้ในกรณีเฉพาะของคุณหรือไม่ แต่ด้วยdiffและpatchเครื่องมืออนุญาตให้แทนที่บางบรรทัดในไฟล์ด้วยบรรทัดอื่น ๆ ได้ค่อนข้างง่าย
Stéphane Gimenez

1
Btw การใช้ข้อมูลแบบสุ่มที่รวบรวมด้วย$()สคริปต์ที่ทำให้ตาของฉันตกแล้ว อย่าใช้ข้อมูลภายนอกในสถานที่ที่อักขระบางตัวถูกตีความด้วยความหมายพิเศษ
Stéphane Gimenez

คำตอบ:


24

ต่อไปนี้เป็นวิธีการเขียนสคริปต์แบบสบาย ๆ (ง่ายต่อการมองมากกว่าที่จะนำไปไว้ในบรรทัดเดียวในบรรทัดคำสั่ง):

/<TEXT1>/ {
  r File1
  d
}

ใช้มัน

$ sed -f script.sed File2
/home/user1/
/home/user2/bin
/home/user1/a/b/c
<TEXT2>

ขอบคุณที่ใช้งานได้ แต่ฉันไม่ต้องการใช้ไฟล์สคริปต์อื่น ๆ มีโซลูชั่นแบบอินไลน์หรือไม่?
chanchal1987

แน่นอน: sed '/<TEXT1>/{rFile1^Md^M}' File2คุณต้องการกด "return" ที่ ^ M ปัญหาคือว่า sed ต้องขึ้นบรรทัดใหม่ภายใน {... } เพื่อคั่นขอบเขตคำสั่ง r และ d
Kusalananda

6
ด้วย bash สตริงแบบ posix นั้นค่อนข้างสะอาดกว่า:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman

9
นอกจากนี้ยังมี-eสำหรับหนึ่งซับ:sed -e '/<TEXT1>/{r File1' -e 'd}' File2
sdaau

1
และถ้าแทนที่แทนที่ทั้งบรรทัดที่มี<TEXT1>ฉันแค่ต้องการแทนที่สตริงตัวเองออกจากส่วนที่เหลือของสายเหมือนเดิม? ไปยังText1: <TEXT1> Text1: <file_contents>
Robin Winslow

9

ใช้เวลานานพอสมควรในการค้นหาโซลูชันนี้โดยใช้การแทนที่ var โซลูชัน sed ทั้งหมดไม่ทำงานสำหรับฉันเนื่องจากพวกเขาลบทั้งบรรทัดหรือแทนที่ไม่ถูกต้อง

FILE2=$(<file2)
FILE1=$(<file1)
echo "${FILE2//TEXT1/$FILE1}" 

แทนที่ TEXT1 ทั้งหมดที่เกิดขึ้นใน file2 กับเนื้อหาของ file1 ข้อความอื่นทั้งหมดยังคงไม่มีการเปลี่ยนแปลง


ดีมาก. อาจจะเร็วกว่าsedเช่นกันเนื่องจากคำว่า "การขยาย" (การเปลี่ยนที่รู้จัก) เหล่านี้สร้างขึ้นในเปลือกหอย ( bashอย่างน้อย)
เมลโลว์สีเหลือง

7

ฉันตอบเพราะdiff/ patchวิธีอาจเป็นที่สนใจในบางกรณี ในการกำหนดการทดแทนบรรทัดที่มีอยู่ในไฟล์blob1ตามบรรทัดที่blob2ใช้งานอยู่:

diff -u blob1 blob2 > patch-file

ตัวอย่างเช่นหากblob1มี:

hello
you

และblob2มี:

be
welcome
here

การสร้างpatch-fileจะเป็น:

--- blob1   2011-09-08 16:42:24.000000000 +0200
+++ blob2   2011-09-08 16:50:48.000000000 +0200
@@ -1,2 +1,3 @@
-hello
-you
+be
+welcome
+here

ตอนนี้คุณสามารถนำ patch นี้ไปใช้กับไฟล์อื่น ๆ ได้:

patch somefile patch-file

มันจะเข้ามาแทนที่hello, youสายโดยbe, welcome, เส้นในheresomefile


นี่มันฉลาดจริงๆ แต่จะดีกว่าถ้าคุณสามารถทำให้มันเป็นสคริปต์ได้โดยอัตโนมัติ
qodeninja
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.