การเพิ่มบรรทัดข้อความให้กับหลาย ๆ ไฟล์


10

ดังนั้นฉันมีไฟล์จำนวนมากในไดเรกทอรีและฉันต้องแทรกบรรทัดข้อความลงในแต่ละไฟล์ พวกเขามีรูปแบบต่อไปนี้เป็นหลัก:


<VirtualHost *:80>
        ServerAdmin gabe@localhost
        DocumentRoot /var/www/test1
        ServerName test1.local
        ServerAlias test1
        <Directory "/var/www/test1">
                Options All
                AllowOverride All
        </Directory>
</VirtualHost>

และฉันต้องการแทรกบรรทัดก่อนปิด

</ VirtualHost>
แท็ก ข้อสันนิษฐานแรกของฉันคือฉันควรจะสามารถทำสิ่งนี้ด้วย sed อาจจับคู่และแทนที่แท็กนั้น ฉันจะเริ่มลองตอนนี้ แต่ถ้าใครมีวิธีการทำเช่นนี้อยู่ฉันก็อยากได้ยิน


ฉันจะซื่อสัตย์เมื่อฉันบอกว่าฉันคิดว่านี่เป็นงานเขียนโปรแกรมมากขึ้น ... และดังนั้นควรเป็นเช่นนั้น ฉันจะใช้ Perl เพื่อทำเช่นนั้นเพราะฉันคิดว่ามีโมดูล Perl ออกแบบมาเพื่อแยกวิเคราะห์และแก้ไข apache configs
xenoterracide

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

คำตอบ:


10

บางสิ่งเช่นนี้

sed 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/'

โรงงาน หากคุณต้องการทำซ้ำคำสั่งนี้กับไฟล์จำนวนมากคุณสามารถทำสิ่งต่อไปนี้:

for i in *; do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' "$i"; done

น่าจะดีกว่า (แต่ยังไม่ทดลอง) ขอบคุณ @ChrisDown:

find . -type f -print0 | while IFS= read -r -d '' filename;\
do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' $filename;\ 
done

ยอดเยี่ยม ... นี่คือสิ่งที่ฉันกำลังมองหา
เกบ

1
ไม่ได้แยกคำสั่ง ls ใช้ glob แทน mywiki.wooledge.org/ParsingLs
Chris Down

คุณแข็งแกร่ง @ChrisDown โปรดปรับปรุงคำตอบของฉัน
lcipriani

การเลือกตัวละครที่แตกต่างจาก/ภาพลักษณ์ที่ดูดีกว่านั้นเป็นเรื่องที่สะอาดกว่าเพราะคุณไม่ต้องหนีจากการทับ:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander

2

ถ้าคุณไม่รังเกียจ Perl ลอง:

perl -pi'*.old' -e 's(</VirtualHost>(Your stuff here\n</VirtualHost>)' myfile

-iสวิทช์จะบันทึกไฟล์เก่าของคุณมี.oldส่วนขยายและพิมพ์ไปยังหนึ่งในปัจจุบัน


2

คุณยังสามารถใช้ "ex" (command-line vi) หากการแก้ไขที่คุณต้องการทำได้ค่อนข้างซับซ้อน ตัวอย่างเช่นคุณต้องการแทรกในหนึ่งอินสแตนซ์ของ "" เท่านั้น

เชลล์สคริปต์แบบนี้สามารถทำงานได้:

for FILENAME in *.whatever  # Need a criteria to glob, or a list of names
do
    ex -s $FILENAME << END_EDITS
/^<\/VirtualHost>/
O " capital-o, not zero
text to insert goes here
.
w!
q
END_EDITS
done

วิธีการนี้ให้ข้อดีของ "อดีต": การค้นหาตำแหน่งที่มีรูปแบบ elaboarte และ 'การเคลื่อนไหวของเคอร์เซอร์' คุณสามารถทำสิ่งต่าง ๆ เช่นค้นหาลวดลายจากนั้นค้นหาอินสแตนซ์ถัดไปจากนั้นทำการแทรก หรือคุณสามารถเปลี่ยนข้อความได้มากกว่าแค่การแทรก หรือคุณสามารถเปลี่ยนระหว่างช่วง อย่าลืมว่า "อดีต" ให้คุณใช้ "" เป็นบรรทัดปัจจุบันดังนั้น. / ^ somepatter / s / blah / foo / จะทำงาน


0

คุณสามารถใช้รหัสบรรทัดเดียวต่อไปนี้เพื่อแทรกบรรทัดเดียวหรือหลายบรรทัดลงในตำแหน่งที่กำหนดในไฟล์ในกรณีของคุณก่อน 'VirtualHost' รหัสนั้นจะค้นหาชื่อไฟล์ (อาจเป็น *. * หากคุณต้องการแทรกข้อความในไฟล์ทั้งหมด) ภายในไดเรกทอรีที่กำหนดและไดเรกทอรีย่อย ภายในไฟล์ที่พบมันจะค้นหารูปแบบ 'VirtualHost' หลังจากพบรูปแบบแล้วจะแทนที่ด้วย Firstline \ nsecondline \ notherlines \ n \ VirtualHost โปรดทราบว่า 'VirtualHost' เป็นส่วนหนึ่งของข้อความเพื่อทดแทนมิฉะนั้นเราจะสูญเสียมัน

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.