Bagaimana cara menyisipkan baris ke file tertentu di mana string tidak ada?

0

Saya mencari bantuan dengan skrip kecil.

Saya ingin mencari semua file yang terkait

/usr/local/directadmin/data/users/*/httpd.conf

untuk string

centralized.log

Jika string tidak ada dalam file, saya ingin memasukkan 2 baris ke dalamnya.

Saat ini saya memiliki skrip berikut:

#!/bin/bash
if ! grep -q centralized.log /usr/local/directadmin/data/users/*/httpd.conf ; then
sed -i '33iCustomLog /var/log/centralized.log combined' /usr/local/directadmin/data/users/*/httpd.conf && sed -i '65iCustomLog /var/log/centralized.log combined' /usr/local/directadmin/data/users/*/httpd.conf
fi

Saat ini, jika string tidak ditemukan di salah satu file, garis dimasukkan ke semua file, dan jika string ditemukan di setidaknya satu file, tidak ada yang terjadi. Bisakah saya membuatnya sehingga baris bisa ditambahkan ke semua file di mana string tidak ada?

wtptrs
sumber
Anda perlu memeriksa setiap file satu per satu: cara termudah jika menggunakan a for lingkaran, misalnya for f in /usr/local/directadmin/data/users/*/httpd.conf ; do if ! grep -q centralized.log "$f" ; then sed -i ... "$f" ; fi ; done.
AFH
menggunakan grep -v Meniadakan pencarian ke string yang tidak ditemukan -R akan mencari semua sub-direktori, jika Anda menginginkannya.
cybernard

Jawaban:

0

Ini harus melakukan trik:

#!/bin/bash
for f in /usr/local/directadmin/data/users/*/httpd.conf ; do
  if ! grep -q centralized.log "$f" ; then
    sed -i '33iCustomLog /var/log/centralized.log combined' "$f" ;
    sed -i '65iCustomLog /var/log/centralized.log combined' "$f" ;
  fi ;
done

Anda dapat menyatukan kedua garis sed, tetapi saya tetap sedekat mungkin dengan contoh Anda.

Alex Stragies
sumber
0
for f in $(grep -l centralized.log /usr/local/directadmin/data/users/*/httpd.conf);
do
  sed -i '33iCustomLog /var/log/centralized.log combined' "$f" && \
  sed -i '65iCustomLog /var/log/centralized.log combined' "$f"
done

Ini hanya mengulangi semua file yang terdaftar oleh grep. Saya pikir ini lebih mudah dibaca dengan cara ini.

EDIT: versi tangguh

function dofile {
  sed -i '33iCustomLog /var/log/centralized.log combined' "$1" && \
  sed -i '65iCustomLog /var/log/centralized.log combined' "$1"
}
grep -l centralized.log /usr/local/directadmin/data/users/*/httpd.conf | while read -r; do dofile "$REPLY"; done

Lihat jawaban ini untuk memahami hal di atas dengan lebih baik.

EDIT2: Semoga ini akan memuaskan @ alex-stragies. Terus edit sebelumnya untuk catatan.

find /usr/local/directadmin/data/users/ -maxdepth 2 -mindepth 2 -name httpd.conf | \
xargs -L1 -I% sh -c \
"sed -i '33iCustomLog /var/log/centralized.log combined' % && sed -i '65iCustomLog /var/log/centralized.log combined' %"

Jika pengguna dapat diberi nama dengan % char, ubah saja sesuai keinginan.

Felipe Lema
sumber
Bukankah grep pertama dan kedua hilang argumen?
Alex Stragies
Memang. Baru saja dikoreksi.
Felipe Lema
Setelah Anda menambahkan baris #! / Bin / bash, dan memperhitungkan kompleksitas subkulit / overhead, saya tidak berpikir contoh Anda lebih baik / lebih cepat / lebih banyak_baca. Jelas butuh lebih banyak waktu untuk menjelaskan kepada seorang bash pemula.
Alex Stragies
Saya ingin memeras setiap alat. Aku bahkan tidak tahu tentang itu -q argumen sampai pertanyaan ini. Ini karena saya pikir lebih baik untuk abstrak sendiri dari masalah: daripada berkomunikasi dengan grep (melalui -q dan if ), Saya "hanya ingin" itu daftar file (untuk file dalam "daftar khusus yang ditentukan").
Felipe Lema
Solusi Anda masih memiliki masalah yang sama seperti sebelum EDIT Anda. Grep akan tersedak ketika diberikan terlalu banyak file. Kompleksitas yang tidak diperlukan dari solusi Anda telah meningkat karena Anda telah memperkenalkan definisi fungsi dan baca bawaan. Dan sekarang Anda memiliki fungsi yang tidak terpakai mengotori lingkungan Anda.
Alex Stragies