Heredoc'u yuvalamanın girintisini eşleştirmek için girintilemez


62

Senaryo için "İlk Dünya Sorunları" varsa, bu olurdu.

Güncelleştirdiğim bir komut dosyasında aşağıdaki kodu var:

if [ $diffLines -eq 1 ]; then
        dateLastChanged=$(stat --format '%y' /.bbdata | awk '{print $1" "$2}' | sed 's/\.[0-9]*//g')

        mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<EOI
        Last Change: $dateLastChanged

        This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
EOI

else
        echo "$diffLines have changed"
fi

Betik sorunsuz e-posta gönderir, ancak mailx komutu bir if ifadesinin içine yerleştirilmiştir, bu yüzden iki seçenekle kalıyorum:

  1. EOIYeni bir satıra koyun ve girinti düzenlerini ya da
  2. Girinti ile devam edin ancak mailx'i e-postamı emmek için yankı ifadesi gibi bir şey kullanın.

Heredoc alternatiflerine açığım, ancak bunu çözmenin bir yolu varsa bu benim tercihim sözdizimdir.

Yanıtlar:


113

Here-doc operatörünü olarak değiştirebilirsiniz <<-. Daha sonra hem burada-doc hem de sınırlayıcıyı sekmelerle girintiliştirebilirsiniz :

#! /bin/bash
cat <<-EOF
    indented
    EOF
echo Done

Burada dokümanı girintili yapmak için boşluk kullanmak yerine sekmeleri kullanmanız gerektiğini unutmayın . Bu, yukarıdaki örneğin kopyalanmayacağı anlamına gelir (Stack Exchange sekmeleri boşluklarla değiştirir). İlk EOFsınırlayıcı etrafında herhangi bir alıntı yapılamaz , aksi takdirde parametre genişletme, komut değiştirme ve aritmetik genişletme etkin değildir.


Harika, bu girinti problemini düzeltir, ancak şimdi $dateLastChanged, örneklemeye hipen + tırnakları bir şey koyarsam, oraya koymaya çalıştığım değişkeni genişletmiyor , ancak tire ve tırnak işaretleri alıp EOI'yi bir Yeni hat tekrar genişlemeye başlar.
— Bratchley

1
@JoelDavis: Sadece tırnak işaretlerini kaldırın, kısa çizgiyi tutun.
— choroba

5
Sekmeleri kullanmaya zorlanmak çok can sıkıcı. Etrafında iyi bir yol var mı?
— con-f kullanımlık

2
@ con-f-use: Gibi bir şey deneyebilirsiniz cat << EOF | sed 's/^ *//'.
— choroba

4
Veya daha iyi cat <<- EOF | awk 'NR==1 && match($0, /^ +/){n=RLENGTH} {print substr($0, n+1)}'. Bu, ilk satırdaki önceki boşlukların miktarını, bu belgedeki her satırdan kaldırır ( anubhava sayesinde ).
— con-f kullanımlık

5

Burada belgenizde komut değiştirme ve parametre genişletmeye gerek duymuyorsanız, sınırlayıcıya baştaki boşlukları ekleyerek sekmeleri kullanmaktan kaçınabilirsiniz:

$     cat << '    EOF'
>         indented
>     EOF
        indented
$     cat << '    EOF' | sed -r 's/^ {8}//'
>         unindented
>     EOF
unindented

Yine de, bu numarayı kullanmanın ve parametre genişlemesini sürdürmenin bir yolunu bulamadım.


1
Bana göre, girinti problemini boşluk kullanmadan çözen tek cevap bu. shell-checkAlıntı yapılan dizgideki boşluklarla uyuşmayan herhangi bir girinti değişikliği bulacaktır. Parametre genişletme için çift tırnak kullanın?
— Tom Hale

4

Bunu dene:

sed 's/^ *//' >> ~/Desktop/text.txt << EOF
    Load time-out reached and nothing to resume.
    $(date +%T) - Transmission-daemon exiting.
EOF

Heredoc içinde farklı girintili çizgiler olamaz, bu durumda. (Bu örneğin içerikleri bir script ise önemlidir.)
— ivan_pozdeev

2

Hmm ... Görünüşe göre buradaki --formatargümandan daha iyi faydalanabiliyor --printfve sadece bir borunun üzerinden geçiyorsunuz. Ayrıca, sizin if...fibir bileşik komuttur - tüm içerilen komutların miras alacağı bir yönlendirme alabilir, bu yüzden belki de heredocu yerleştirmeniz gerekmez.

if      [ "$diffLines" = 1 ]
then    stat --printf "Last Change: %.19y\n\n$(cat)\n" /.bbdata |
        mailx   -r  "Systems and Operations <sysadmin@[redacted].edu>" \
                -s  "Warning Stale BB Data" 'jadavis6@[redacted].edu'
else    echo    "$diffLines have changed"
fi      <<\STALE
This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
STALE

Evet önceki revizyonum sed/ awkkısmına aldırmadığımı söyledi . Bugünkü revizyonumun bir kısmı, soruya alman olmadığı için çıkarmaktı. Her iki durumda da diğerinden yarım düzine altı.
— Bratchley

@ Bratchley - kahretsin. Bu son cümle, günün geri kalanında beni rahatsız edecek.
— mikeserv,

Ne demek istiyorsun?
— Bratchley

1
@Bratchley - Bir bilmece gibi görünüyor.
— mikeserv

Ha. Hangi ülkeden geldiğinizden emin değilim ama bu, Amerika Birleşik Devletleri'nde yaygın bir ifadedir. Sadece "Aynı sonuca farklı yaklaşım" demek. Çözümünüz heredoc etrafında olsa da.
— Bratchley

0

Diğer yöntem herestrings olacaktır:

    mail_content="Last Change: $dateLastChanged

    This is an automated warning of stale data for the UNC-G Blackboard Snapshot process."
    mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<<"$mail_content"
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.