Menambahkan satu baris teks ke banyak file

10

Jadi, saya punya banyak file di direktori, dan saya harus memasukkan satu baris teks ke masing-masing. Mereka pada dasarnya memiliki format berikut:


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

Dan saya ingin memasukkan garis sebelum penutupan

</VirtualHost>
menandai. Asumsi pertama saya adalah bahwa saya harus dapat melakukan ini dengan sed, mungkin mencocokkan dan mengganti tag itu. Saya akan mulai mencoba ini sekarang, tetapi jika ada yang punya cara untuk melakukan ini, saya ingin mendengarnya.

gabe
sumber
Saya akan jujur ​​ketika saya mengatakan saya pikir ini lebih dari tugas pemrograman ... dan karenanya harus di SO. Saya akan menggunakan Perl untuk melakukannya, terutama karena saya yakin ada modul perl yang dirancang untuk menguraikan, dan memodifikasi konfigurasi apache.
xenoterracide
2
Terima kasih, tetapi ini adalah tugas yang harus mudah diselesaikan dengan alat unix sederhana, karenanya ditanyakan di sini. Terima kasih atas komentar Anda.
gabe.

Jawaban:

10

Sesuatu seperti ini:

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

bekerja. Jika Anda ingin mengulangi perintah ini pada banyak file, Anda dapat melakukan sesuatu seperti:

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

Mungkin lebih baik (tetapi belum teruji) berkat @ChrisDown:

find . -type f -print0 | while IFS= read -r -d '' filename;\
do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' $filename;\ 
done
lcipriani
sumber
Luar biasa ... ini hanya apa yang saya cari.
gabe.
1
Jangan tidak mengurai ls. Gunakan gumpalan sebagai gantinya. mywiki.wooledge.org/ParsingLs
Chris Down
Anda rigid @ChrisDown. Tolong, tingkatkan jawaban saya.
lcipriani
Memilih karakter yang berbeda daripada /untuk ekspresi sed lebih bersih, karena Anda tidak harus melarikan diri dari tebasan:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander
2

Jika Anda tidak keberatan Perl coba:

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

The -iswitch akan menyimpan file lama Anda dengan .oldekstensi dan cetak dengan yang sekarang.

gvkv
sumber
2

Anda juga dapat menggunakan "ex" (baris perintah vi) jika pengeditan yang ingin Anda lakukan bahkan agak rumit. Misalnya, Anda hanya ingin melakukan penyisipan untuk satu contoh "".

Script shell seperti ini dapat bekerja:

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

Pendekatan ini memberi Anda keuntungan "ex": menemukan lokasi dengan pola elaboarte, dan 'gerakan kursor'. Anda dapat melakukan hal-hal seperti menemukan pola, kemudian menemukan contoh berikutnya, MAKA lakukan penyisipan. Atau Anda dapat mengubah teks, bukan hanya melakukan sisipan. Atau Anda dapat mengubah antar rentang. Jangan lupa bahwa "mantan" memungkinkan Anda menggunakan "." sebagai baris saat ini, maka., / ^ somepatter / s / blah / foo / akan bekerja.

Bruce Ediger
sumber
0

Anda dapat menggunakan kode baris tunggal berikut untuk menyisipkan satu baris atau beberapa baris ke lokasi yang diberikan dalam file, dalam kasus Anda sebelum 'VirtualHost'. Kode ini pada dasarnya mencari nama file (bisa jadi *. *, Jika Anda ingin memasukkan teks di semua file) dalam direktori yang diberikan dan sub-direktori. Dalam file yang ditemukan, ia mencari pola 'VirtualHost'. Setelah ditemukan polanya, ia menggantinya dengan firstline \ nsecondline \ notherlines \ n \ VirtualHost. Perhatikan bahwa 'VirtualHost' adalah bagian dari teks untuk penggantian, kalau tidak kita akan kehilangan itu.

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
Oufie
sumber