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.