Birden çok dosyaya metin satırı ekleme


10

Yani, bir dizinde bir sürü dosya var ve her birine bir metin satırı eklemem gerekiyor. Aslında aşağıdaki biçime sahiptirler:


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

Ve kapanmadan önce bir çizgi eklemek istiyorum

</ VirtualHost>
etiket. İlk varsayım, bunu sed ile yapabilmem gerektiğidir, muhtemelen bu etiketi eşleştirerek ve değiştirerek. Bunu şimdi denemeye başlayacağım, ancak herhangi birinin bunu yapmak için mevcut bir yolu varsa, duymak isterim.


Bunun bir programlama görevi olduğunu düşündüğümü söylediğimde dürüst olacağım ... ve bu yüzden SO'da olmalı. Bunu yapmak için Perl kullanırdım, çünkü apache yapılandırmalarını ayrıştırmak ve değiştirmek için tasarlanmış bir perl modülü olduğundan eminim.
xenoterracide

2
Teşekkürler, ancak basit unix araçlarıyla başarılması kolay bir görev, bu yüzden burada sordu. Yine de yorumunuz için teşekkürler.
gabe.

Yanıtlar:


10

Bunun gibi bir şey:

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

İşler. Bu komutu bir çok dosyada tekrarlamak isterseniz, aşağıdakine benzer bir şey yapabilirsiniz:

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

@ChrisDown sayesinde muhtemelen daha iyi (ama denenmemiş):

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

harika ... bu sadece aradığım şeydi.
gabe.

1
Do not ls ayrıştırmak. Bunun yerine bir glob kullanın. mywiki.wooledge.org/ParsingLs
Chris Down

@ChrisDown sizsiniz. Lütfen, cevabımı geliştir.
lcipriani

/Eğer eğik çizgi kaçmak zorunda değilsiniz çünkü sed ifadesi için farklı bir karakter seçmek daha temiz:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander

2

Perl'in sakıncası yoksa şunu deneyin:

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

-iAnahtar bir ile eski dosyayı kurtaracak .oldcari birine uzantısı ve baskı.


2

Yapmak istediğiniz düzenleme biraz karmaşıksa "ex" (komut satırı vi) işlevini de kullanabilirsiniz. Örneğin, eki yalnızca bir "" örneğinde yapmak istiyorsunuz.

Bunun gibi bir kabuk komut dosyası çalışabilir:

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

Bu yaklaşım size "eski" nin avantajlarını sunar: ayrıntılı kalıpları olan bir yer bulma ve "imleç hareketleri". Bir desen bulmak gibi şeyler yapabilir, ardından bir sonraki örneği bulabilirsiniz, SONRA eki yapın. Veya yalnızca ekler yapmak yerine metni değiştirebilirsiniz. Veya aralıklar arasında geçiş yapabilirsiniz. Unutmayın "eski" kullanmanıza izin verir. " geçerli satır olarak,., / ^ somepatter / s / blah / foo / çalışacaktır.


0

Bir dosyadaki belirli bir konuma, 'VirtualHost' öncesi bir tek satır veya birden çok satır eklemek için aşağıdaki tek satır kodunu kullanabilirsiniz. Kod temel olarak verilen dizinde ve alt dizinlerinde dosya adını (tüm dosyalara metin eklemek isterseniz *. * Olabilir) arar. Bulunan dosyalar içinde 'VirtualHost' kalıbını arar. Deseni bulduktan sonra, ilk satırın \ nsecondline \ notherlines \ n \ VirtualHost ile değiştirir. 'VirtualHost' öğesinin değiştirilecek metnin bir parçası olduğunu unutmayın, aksi takdirde onu kaybederiz.

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.