Menyisipkan baris setelah pertandingan pertama menggunakan sed

Untuk beberapa alasan aku bisa't tampaknya menemukan langsung jawaban untuk ini dan saya'm di saat krisis saat ini. Bagaimana saya pergi tentang memasukkan pilihan baris teks setelah baris pertama pencocokan string tertentu menggunakan sed perintah. Saya memiliki ...

CLIENTSCRIPT="foo"
CLIENTFILE="bar"

Dan aku ingin menyisipkan baris setelah CLIENTSCRIPT= baris yang dihasilkan di ...

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
Larutan

Cobalah melakukan hal ini menggunakan GNU sed:

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

jika anda ingin mengganti in-place, menggunakan

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

Output

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

Doc

  • lihat sed doc dan pencarian \a (append)
Komentar (14)

Perhatikan standar sed sintaks (seperti dalam POSIX, sehingga didukung oleh semua sesuai sed implementasi di sekitar (GNU, OS/X, BSD, Solaris...)):

sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file

Atau pada satu baris:

sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file

(-e'xpressions (dan isi-f'iles) yang bergabung dengan baris baru untuk membuat script sed sed menafsirkan).

The -i opsi untuk di-tempat editing juga GNU ekstensi, beberapa implementasi lain (seperti FreeBSD's) dukungan -i '' untuk itu.

Atau, untuk portabilitas, anda dapat menggunakan perl sebagai gantinya:

perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file

Atau anda bisa menggunakan ed atau ex:

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file
Komentar (4)

POSIX-compliant satu menggunakan perintah s:

sed '/CLIENTSCRIPT="foo"/s/.*/&\
CLIENTSCRIPT2="hello"/' file
Komentar (2)

Sed perintah yang bekerja pada MacOS (setidaknya, OS 10) dan Unix yang sama (ie. doesn't membutuhkan gnu sed seperti Gilles' (berlaku saat ini) tidak):

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file

Ini bekerja di bash dan mungkin kerang lainnya juga yang tahu $'\n' evaluasi penawaran gaya. Semuanya bisa pada satu baris dan bekerja di lebih tua/POSIX sed perintah. Jika mungkin ada beberapa baris yang cocok dengan CLIENTSCRIPT="anu" (atau setara) dan anda hanya ingin menambahkan baris tambahan pertama kalinya, anda dapat mengolah hal sebagai berikut:

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file

(ini menciptakan lingkaran setelah penyisipan baris kode yang hanya siklus melalui seluruh file, tidak pernah kembali untuk pertama sed perintah lagi).

Anda mungkin melihat saya menambahkan '^ *' untuk pencocokan pola dalam kasus garis yang muncul di komentar, berkata, atau lebih menjorok ke dalam. Yang tidak 100% sempurna, tetapi meliputi beberapa situasi lain mungkin umum. Menyesuaikan seperti yang diperlukan...

Kedua solusi ini juga mendapatkan putaran masalah (untuk solusi generik untuk menambahkan baris) bahwa jika anda baru dimasukkan baris berisi tidak lolos garis miring terbalik atau ampersand mereka akan ditafsirkan oleh sed dan kemungkinan besar tidak akan keluar sama, seperti \n - misalnya. \0 akan menjadi baris pertama yang cocok. Terutama berguna jika anda're menambahkan garis yang berasal dari suatu variabel di mana anda'd jika tidak memiliki untuk melarikan diri segala sesuatu yang pertama menggunakan ${var//} sebelumnya, atau yang lain sed pernyataan dll.

Solusi ini kurang sedikit berantakan di script (yang mengutip dan \n tidak mudah dibaca meskipun), ketika anda don't ingin menempatkan teks pengganti untuk perintah di mulai dari garis jika mengatakan, dalam sebuah fungsi dengan indentasi baris. I've mengambil keuntungan yang $'\n' adalah evaluasi untuk newline oleh shell, yang tidak reguler '\n' satu-dikutip nilai-nilai.

Sudah cukup lama meskipun saya pikir perl/bahkan awk mungkin menang karena menjadi lebih mudah dibaca.

Komentar (2)

Aku punya tugas yang sama, dan tidak mampu untuk mendapatkan di atas perl solusi untuk pekerjaan.

Berikut ini adalah solusi saya:

perl -i-pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf

Penjelasan:

Menggunakan ekspresi reguler untuk mencari baris di /etc/mysql/my.cnf file yang hanya berisi [mysqld] dan diganti dengan

[mysqld] pemeriksaan-server = utf8_unicode_ci

secara efektif menambahkan pemeriksaan-server = utf8_unicode_ci baris setelah baris yang mengandung [mysqld].

Komentar (0)

Yang awk varian :

awk '1;/CLIENTSCRIPT=/{print "CLIENTSCRIPT2=\"hello\""}' file
Komentar (1)

Mungkin sedikit terlambat untuk posting jawaban untuk ini, tapi saya menemukan beberapa solusi di atas sedikit rumit.

Saya mencoba string sederhana penggantian hard disk sed dan bekerja:

sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

& tanda mencerminkan cocok string, dan kemudian anda tambahkan \n dan baris baru.

Seperti yang disebutkan, jika anda ingin melakukannya di tempat:

sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

Lain hal. Anda dapat mencocokkan dengan menggunakan ungkapan:

sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file

Semoga ini bisa membantu seseorang

Komentar (0)