Bir metin dosyasının işaretçiler arasındaki kısmını başka bir metin dosyasıyla nasıl değiştiririm?


26

Diyelim ki böyle bir metin dosyası var:

# custom content section
a
b

### BEGIN GENERATED CONTENT
c
d
### END GENERATED CONTENT

GENERATED CONTENTEtiketler arasındaki bölümü başka bir dosyanın içeriğiyle değiştirmek istiyorum .

Bunu yapmanın en basit yolu nedir?

Yanıtlar:


36
lead='^### BEGIN GENERATED CONTENT$'
tail='^### END GENERATED CONTENT$'
sed -e "/$lead/,/$tail/{ /$lead/{p; r insert_file
        }; /$tail/p; d }"  existing_file

Mükemmel. sedsadece çok daha fazlasını yapabilir s/.../...!
DevSolar

Hmmm benim için çalışmıyor, sed komutunu bir satıra mı koymalıyım?
lzap

3
r insert_fileKomut kendi satırında son şey olmalı. Boşluğa veya yorumlara bundan sonra izin verilmediğini unutmayın . Kod GNU kullanılarak test edilmiştir sedile --posixseçeneği etkin ve beklendiği gibi herhangi biriyle çalışmalıdır yüzden çalıştı POSIX uyumlu sed .
Peter.O

1
Kutsal moly, bu harika! Bu benim baş sözlüğüme gidiyor! Son derece yararlı ve güzel basit. Teşekkür ederim!
DanielSmedegaardBuus

2
Yerinde düzenleme, sed (örneğin output=$(sed -e "..." existing_file)) çıktısını yakalamanızı ve ardından ikinci bir geçişte (örn. echo "$output" > existing_file) Değiştirme işlemini gerçekleştirmenizi gerektirir, çünkü okuduğunuz bir dosyaya yönlendirmeyi denemek içeriği okumadan önce kesmesine neden olur.
Chris Tonkinson

5
newContent=`cat new_file`
perl -0777 -i -pe "s/(### BEGIN GENERATED CONTENT\\n).*(\\n### END GENERATED CONTENT)/\$1$newContent\$2/s" existing_file

İyi iş. Benimkinden çok daha basit. :)
Dr Kitty

4

Uyarı: Bu kesinlikle bunu yapmanın en kolay yolu değil. (EDIT: bash çalışır; POSIX grep de iyidir)

Ana metin "main" dosyasında ve oluşturulan içerik "gen" dosyasındaysa, aşağıdakileri yapabilirsiniz:

#!/bin/bash
BEGIN_GEN=$(cat main | grep -n '### BEGIN GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
END_GEN=$(cat main | grep -n '### END GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
cat <(head -n $(expr $BEGIN_GEN - 1) main) gen <(tail -n +$(expr $END_GEN + 1) main) >temp
mv temp main

Bu çalışıyor mu? Sanırım son satırınız mainkedi tarafından okunmadan önce yazmak, temizlemek için açılıyor .
chepner

@chepner Crap, haklısın. Gerisi olsa çalışır. Düzelteceğim.
Dr Kitty

3
ed -s FILE1 <<EOF
/### BEGIN GENERATED/+,/### END GENERATED/-d
/### BEGIN GENERATED/ r FILE2
w
q
EOF

Heredoc ve ed çizgi editörü kullanarak. Heredoc içindeki ilk satır 'd' ve '#' satırından sonra '## BEGIN GENERATED ...' satırını ve '-' 'önceki satırdan' # '### END GENERATED ...'
FILE2

üzgünüm demek istediğim
FILE2

Benim için sakin ol millet, benim ilk seferimden sonra :-). Ayrıca aynı kelimeyi kullanmış olabilirim, ancak diğer çözümde bir heredocs değil, bir printf ve bir boru kullanılıyor. Herhangi bir yol özür i bir hata :-) yaptıysanız
Jetchisel

Teşekkürler, çok okunabilir! BTW - yerine farklı bir komut dosyasından okumak r FILE2için söyleyebilirsiniz r !command.
İstanköy
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.