Çok satırlı bir komut içindeki bir Bash komut dosyasına yorum yapma


165

Bir komut dosyasından aşağıdaki satırların her satırına nasıl yorum yapabilirim?

cat ${MYSQLDUMP} | \
sed '1d' | \
tr ",;" "\n" | \
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
tr "\n" "," | \
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

Eğer denemek ve gibi bir yorum eklemek:

cat ${MYSQLDUMP} | \ # Output MYSQLDUMP File

Alırım:

#: not found

Burada yorum yapmak mümkün mü?


1
Fark ettiğiniz gibi, önce # yaparsanız, \ yorumun sadece bir parçası olur, ancak önce \ yaparsanız, satırdaki sonraki karakterler anlamını "satır devamından" "alıntı" olarak değiştirir. Aşağıda verilen bir çözümü düşündüm.
DigitalRoss

Yanıtlar:


204

Bunun biraz yükü olacak, ancak teknik olarak sorunuza cevap veriyor:

echo abc `#Put your comment here` \
     def `#Another chance for a comment` \
     xyz, etc.

Ve özellikle boru hatları için, ek yükü olmayan temiz bir çözüm var:

echo abc |        # Normal comment OK here
     tr a-z A-Z | # Another normal comment OK here
     sort |       # The pipelines are automatically continued
     uniq         # Final comment

Bkz yığın taşması soru bir Multi-line Komut için Hat Yorum Put .


1
Daha basit bir yöntem yoksa, oldukça karmaşık görünüyor?
BassKozz

1
Tamam, biraz daha basit bir varyasyon ekledim.
DigitalRoss

1
Cevabınızı sadece ters eğik çizginin gerekli olmadığını gösterecek şekilde değiştirebilir misiniz, böylece yorumları her satırın yanına koyabilir ve sadece bir boru kullanabilir miyim?
BassKozz

Bir ve iki sürümlerin çalıştığını doğruladım. Ancak, neden yaptıklarını ve burada neler olduğunu açıklayabilir misiniz? Teşekkürler.
Faheem Mitha

1
Açıklama için teşekkürler. Unix.sx hakkında daha fazla ayrıntı isteyen bir soru açtım , devam karakterinden sonra yorumlarla bash çok satırlı komut .
Faheem Mitha

39

Sondaki ters eğik çizgi, devam komutu olarak yorumlanabilmesi için satırdaki son karakter olmalıdır. Bundan sonra hiçbir yoruma ve hatta boşluklara izin verilmez.

Komutlarınızın arasına yorum satırları koymanız gerekir

# output MYSQLDUMP file
cat ${MYSQLDUMP} | \
# simplify the line
sed '/created_at/d' | \
# create some newlines
tr ",;" "\n" | \
# use some sed magic
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
# more magic
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
# even more magic
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
tr "\n" "," | \
# I hate phone numbers in my output
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \ 
# one more sed call and then send it to the CSV file
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

12
Boru hattı komut bileşeni | ile bitince \ gerekli değildir.
DigitalRoss

2
DigitalRoss, haklısın, sadece ters eğik çizgiyi değil boruyu kullanabilirim ve sonra #comments mükemmel bir şekilde çalışacaktır ... Bunu cevap olarak gönderebilirsin, böylece kabul edebilirim.
BassKozz

8
"Komutlarınız arasına yorum satırları koyabilmelisiniz": Hayır, bu sadece önceki satırların en son yorumlanan karakteri olduğu için çalışıyor |. Eğer denerseniz cat file1\<newline>#comment<newline>file2, alamadığınızı görürsünüz cat file1 file2, aksine cat file1; file2.
dubiousjim

5
Ancak, diğerlerinin de belirttiği gibi, cat file1 | # comment<newline>sortiyi çalışıyor. Aynı şekilde cat file1 && # comment<newline>echo foo. Comments sonra dahil edilebilir Yani |ya &&ya ||, fakat sonra `\` ya bir komutun ortasında.
dubiousjim

7

DigitalRoss'un işaret ettiği gibi, çizgi woud'u sona erdiğinde sondaki ters eğik çizgi gerekli değildir |. Aşağıdakileri takip eden bir satıra yorum ekleyebilirsiniz |:

 cat ${MYSQLDUMP} |         # Output MYSQLDUMP file
 sed '1d' |                 # skip the top line
 tr ",;" "\n" | 
 sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' |
 sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' |
 sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' |
 tr "\n" "," |
 sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' |   # hate phone numbers
 sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

5

Ters eğik çizgi, # karakterinden kaçarak yorum karakteri yerine gerçek karakteri olarak yorumlanır.


3

$IFS yorum kesmek

Bu kesmek, komutlardaki kelimeleri ayırmak için kullanılan parametre genişletme özelliğini kullanır $IFS:

$ echo foo${IFS}bar
foo bar

Benzer şekilde:

$ echo foo${IFS#comment}bar
foo bar

Bunu kullanarak, komut satırına devam eden bir yorum ekleyebilirsiniz:

$ echo foo${IFS# Comment here} \
> bar
foo bar

ancak yorumun \devam etmeden önce olması gerekir .

Parametre genişletmenin yorumun içinde yapıldığına dikkat edin:

$ ls file
ls: cannot access 'file': No such file or directory
$ echo foo${IFS# This command will create file: $(touch file)}bar
foo bar
$ ls file
file

Nadir istisna

Bu başarısız olan tek nadir durum, $IFSdaha önce genişletme yoluyla kaldırılan tam metinle (yani, #karakterden sonra ) başlarsa :

$ IFS=x
$ echo foo${IFS#y}bar
foo bar
$ echo foo${IFS#x}bar
foobar

Finalde foobarkonuyu gösteren boş alan olmadığına dikkat edin.

Yana $IFSvarsayılan olarak yalnızca boşluk içeriyor, bu kadar çok bu sorunun içine edeceğiz olası.


Kredi @ PJH yorumuna bu cevabı kapalı yol açtı.


1

DigitalRoss'un örneklerine ek olarak, geri tıklamalar $()yerine tercih ederseniz kullanabileceğiniz başka bir form`

echo abc $(: comment) \
     def $(: comment) \
     xyz

Tabii ki, kolon sözdizimini backticks ile de kullanabilirsiniz:

echo abc `: comment` \
     def `: comment` \
     xyz

ek Notlar

Nedeni $(#comment)işe yaramıyor, çünkü bir kez gördüğü zaman #, satırın geri kalanını kapanış parantezleri de dahil olmak üzere yorum olarak kabul ediyor:comment) . Böylece parantez asla kapalı değildir.

Backticks farklı ayrıştırır ve a sonra bile kapanış backtick tespit edecektir #.


1
Bu her yorum için yeni bir kabuk oluşturacak mı?
Lonix

0

Aşağıda, birkaç önceki yorumun fikirlerini ve deyimlerini birleştiren bir bash betiği, örneklerle genel forma sahip satır içi yorumlar sağlamak için ${__+ <comment text>}.

Özellikle

  • <comment text> çok satırlı olabilir
  • <comment text> parametre genişletilmiş değil
  • alt işlem yapılmaz (bu nedenle yorumlar etkilidir)

Bir kısıtlama üzerinde bulunmaktadır <comment text>, yani dengesiz parantez '}'ve parantez ')'korumalı (yani olmalıdır '\}'ve'\)' ).

Yerel bash ortamında bir gereklilik vardır:

  • parametre adı __ayarlanmamış olmalıdır

Sözdizimsel olarak geçerli olan diğer her bash parametre adı, __ , adın ayarlanmış bir değeri olmaması koşuluyla yerine sunulur.

Aşağıdaki örnek bir komut dosyası

# provide bash inline comments having the form
#     <code> ${__+ <comment>} <code> 
#     <code> ${__+ <multiline
#                   comment>} <code>

# utility routines that obviate "useless use of cat"
function bashcat { printf '%s\n' "$(</dev/stdin)"; }
function scat { 1>&2 bashcat; exit 1; }

# ensure that '__' is unset && remains unset
[[ -z ${__+x} ]] &&  # if '__' is unset
  declare -r __ ||   # then ensure that '__' remains unset 
  scat <<EOF         # else exit with an error
Error: the parameter __='${__}' is set, hence the
  comment-idiom '\${__+ <comment text>}' will fail
EOF

${__+ (example of inline comments)
------------------------------------------------
the following inline comment-idiom is supported
    <code> ${__+ <comment>} <code> 
    <code> ${__+ <multiline
                  comment>} <code> 
(advisory) the parameter '__' must NOT be set;
  even the null declaration __='' will fail
(advisory) protect unbalanced delimiters \} and \) 
(advisory) NO parameter-expansion of <comment> 
(advisory) NO subprocesses are spawned
(advisory) a functionally equivalent idiom is 
    <code> `# <comment>` <code> 
    <code> `# <multiline
               comment>` <code>
however each comment spawns a bash subprocess
that inelegantly requires ~1ms of computation 
------------------------------------------------}
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.