Bash devam hatlarını nasıl kullanıyorsunuz?
Bunu yapabileceğinizin farkındayım:
echo "continuation \
lines"
>continuation lines
Ancak, girintili kod varsa, çok iyi çalışmaz:
echo "continuation \
lines"
>continuation lines
Bash devam hatlarını nasıl kullanıyorsunuz?
Bunu yapabileceğinizin farkındayım:
echo "continuation \
lines"
>continuation lines
Ancak, girintili kod varsa, çok iyi çalışmaz:
echo "continuation \
lines"
>continuation lines
Yanıtlar:
İstediğiniz budur
$ echo "continuation"\
> "lines"
continuation lines
Bu yankı için iki argüman yaratıyorsa ve sadece bir tane istiyorsanız, dize birleşimine bakalım. Bash'da, iki dizeyi yan yana yerleştirerek bitiştirin:
$ echo "continuation""lines"
continuationlines
Yani bir devam çizgi bir girinti olmaksızın bir dize kırmaya bir yoludur:
$ echo "continuation"\
> "lines"
continuationlines
Ancak bir girinti kullanıldığında:
$ echo "continuation"\
> "lines"
continuation lines
İki bağımsız değişken elde edersiniz çünkü bu artık bir birleştirme değildir.
Satırları keserken tek bir dize istiyorsanız, girintileme yaparken ancak tüm bu boşlukları alamıyorsanız, deneyebileceğiniz bir yaklaşım, devam çizgisini atmak ve değişkenleri kullanmaktır:
$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines
Bu, ek değişkenler pahasına temiz bir şekilde girintili kod elde etmenizi sağlayacaktır. Değişkenleri yerel yaparsanız, çok kötü olmamalıdır.
s="string no. 1" s+="string no. 2" s+=" string no. 3" echo "$s"
Burada <<-HERE
sonlandırıcılı belgeler girintili çok satırlı metin dizeleri için iyi çalışır. Buradaki tüm önde gelen sekmeleri kaldırır. (Yine de hat sonlandırıcılar kalacaktır.)
cat <<-____HERE
continuation
lines
____HERE
Ayrıca bkz. Http://ss64.com/bash/syntax-here.html
Tümü olmasa da önde gelen boşlukları korumanız gerekiyorsa, aşağıdaki gibi bir şey kullanabilirsiniz.
sed 's/^ //' <<____HERE
This has four leading spaces.
Two of them will be removed by sed.
____HERE
veya tr
yeni satırlardan kurtulmak için kullanın :
tr -d '\012' <<-____
continuation
lines
____
(İkinci satırda bir sekme ve önde bir boşluk vardır; sekme, yorumlu sonlandırıcıdan önce tire operatörü tarafından kaldırılacak, oysa alan korunacaktır.)
Uzun karmaşık dizeleri birçok satıra sarmak için printf
:
printf '%s' \
"This will all be printed on a " \
"single line (because the format string " \
"doesn't specify any newline)"
Ayrıca, ana bilgisayar dilinin sözdiziminin a Makefile
veya gibi bir burada belgeyi kullanmanıza izin vermeyeceği başka bir dilde önemsiz olmayan kabuk komut dosyası parçalarını gömmek istediğiniz bağlamlarda da iyi çalışır Dockerfile
.
printf '%s\n' >./myscript \
'#!/bin/sh` \
"echo \"G'day, World\"" \
'date +%F\ %T' && \
chmod a+x ./myscript && \
./myscript
printf
şimdi de ilk örneğe bakın .)
Bash dizilerini kullanabilirsiniz
$ str_array=("continuation"
"lines")
sonra
$ echo "${str_array[*]}"
continuation lines
ekstra bir alan var, çünkü (bash kılavuzundan sonra):
Sözcük çift tırnak içine alınmışsa,
${name[*]}
her dizi üyesinin değeri IFS değişkeninin ilk karakteriyle ayrılmış tek bir sözcüğe genişler
IFS=''
Ekstra alandan kurtulmak için ayarlanmış
$ IFS=''
$ echo "${str_array[*]}"
continuationlines
Bazı senaryolarda Bash'ın birleştirme yeteneğini kullanmak uygun olabilir.
temp='this string is very long '
temp+='so I will separate it onto multiple lines'
echo $temp
this string is very long so I will separate it onto multiple lines
isim = [değer] ...
... Bir atama ifadesinin kabuk değişkenine veya dizi dizinine bir değer atadığı bağlamda, + = operatörü değişkenin önceki değerine eklemek veya bu değere eklemek için kullanılabilir. Tamsayı özniteliğinin ayarlandığı bir değişkene + = uygulandığında, değer aritmetik bir ifade olarak değerlendirilir ve değişkenin geçerli değerine eklenir, bu değer de değerlendirilir. Bileşik ataması kullanılarak bir dizi değişkenine + = uygulandığında (aşağıdaki Diziler'e bakın), değişkenin değeri ayarlanmamıştır (= kullanılırken olduğu gibi) ve dizinin maksimum dizininden birinden başlayarak diziye yeni değerler eklenir (dizine alınmış diziler için) veya ilişkilendirilebilir bir dizide ek anahtar / değer çiftleri olarak eklenir. Dize değerli bir değişkene uygulandığında, değer genişletilir ve değişkenin değerine eklenir.
Bir komut argümanının parçası olarak uzun bir mesaj göndermek zorunda olduğum ve satır uzunluğu sınırlamasına uymak zorunda kaldığım bir durumla karşılaştım. Komutlar şöyle görünür:
somecommand --message="I am a long message" args
Bunu çözdüğüm yol, mesajı burada bir belge olarak (@tripleee önerilen gibi) dışarı taşımaktır. Ama burada bir belge stdin oluyor, bu yüzden tekrar okunması gerekiyor, aşağıdaki yaklaşımla gittim:
message=$(
tr "\n" " " <<- END
This is a
long message
END
)
somecommand --message="$message" args
Bunun avantajı, $message
ekstra boşluk veya satır kesmeleri olmadan tam olarak dize sabiti olarak kullanılabilmesidir.
Yukarıdaki gerçek mesaj satırlarının tab
her birinin, burada kullanıldığından (kullanımından dolayı <<-
) ayrılan bir karakterle öneki olduğuna dikkat edin . Sonunda hala satır araları var ve bunlar dd
boşluklarla değiştiriliyor .
Ayrıca, yeni satırları kaldırmazsanız, bu satırlar "$message"
genişletildiğinde olduğu gibi görüneceğini unutmayın . Bazı durumlarda, çift tırnak işaretlerini kaldırarak geçici çözüm bulabilirsiniz $message
, ancak ileti artık tek bir bağımsız değişken olmayacaktır.
Satır devamları sözdiziminin akıllıca kullanılmasıyla da sağlanabilir.
Aşağıdaki durumlarda echo
:
# echo '-n' flag prevents trailing <CR>
echo -n "This is my one-line statement" ;
echo -n " that I would like to make."
This is my one-line statement that I would like to make.
Vars durumunda:
outp="This is my one-line statement" ;
outp+=" that I would like to make." ;
echo -n "${outp}"
This is my one-line statement that I would like to make.
Varlık durumunda başka bir yaklaşım:
outp="This is my one-line statement" ;
outp="${outp} that I would like to make." ;
echo -n "${outp}"
This is my one-line statement that I would like to make.
İşte bu kadar!
Girintinin içinde gerektiği gibi yeni satırlarla (ters eğik çizgi kullanmadan) ve yalnızca yeni satır şeridi ile ayırabilirsiniz.
Misal:
echo "continuation
of
lines" | tr '\n' ' '
Veya değişken bir tanımsa, yeni satırlar otomatik olarak boşluklara dönüştürülür. Bu nedenle, yalnızca varsa ek boşlukları soyun.
x="continuation
of multiple
lines"
y="red|blue|
green|yellow"
echo $x # This will do as the converted space actually is meaningful
echo $y | tr -d ' ' # Stripping of space may be preferable in this case
Bu tam olarak kullanıcının sorduğu bir şey değildir, ancak birden fazla satıra yayılan uzun bir dize oluşturmanın başka bir yolu, bunu aşamalı olarak oluşturmaktır:
$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World
Açıkçası bu durumda bir seferlik inşa etmek daha kolay olurdu, ancak bu stil daha uzun dizelerle uğraşırken çok hafif ve anlaşılabilir olabilir.
Ancak, girintili kod varsa, çok iyi çalışmaz:
echo "continuation \ lines" >continuation lines
Tek tırnak işareti ve dizeleri birleştirmeyi deneyin:
echo 'continuation' \
'lines'
>continuation lines
Not: birleştirme bir boşluk içerir.
echo
sen olsaydı x=
, hatayı almak istiyorum: lines: command not found
.
Ne tür riskleri kabul edeceğinize ve verileri ne kadar iyi bildiğinize ve güvendiğinize bağlı olarak, basit değişken enterpolasyonunu kullanabilirsiniz.
$: x="
this
is
variably indented
stuff
"
$: echo "$x" # preserves the newlines and spacing
this
is
variably indented
stuff
$: echo $x # no quotes, stacks it "neatly" with minimal spacing
this is variably indented stuff
Bu muhtemelen sorunuza gerçekten cevap vermiyor, ancak yine de yararlı olabilir.
İlk komut, ikinci komut tarafından görüntülenen komut dosyasını oluşturur.
Üçüncü komut bu komut dosyasını yürütülebilir hale getirir.
Dördüncü komut bir kullanım örneği sağlar.
john@malkovich:~/tmp/so$ echo $'#!/usr/bin/env python\nimport textwrap, sys\n\ndef bash_dedent(text):\n """Dedent all but the first line in the passed `text`."""\n try:\n first, rest = text.split("\\n", 1)\n return "\\n".join([first, textwrap.dedent(rest)])\n except ValueError:\n return text # single-line string\n\nprint bash_dedent(sys.argv[1])' > bash_dedent
john@malkovich:~/tmp/so$ cat bash_dedent
#!/usr/bin/env python
import textwrap, sys
def bash_dedent(text):
"""Dedent all but the first line in the passed `text`."""
try:
first, rest = text.split("\n", 1)
return "\n".join([first, textwrap.dedent(rest)])
except ValueError:
return text # single-line string
print bash_dedent(sys.argv[1])
john@malkovich:~/tmp/so$ chmod a+x bash_dedent
john@malkovich:~/tmp/so$ echo "$(./bash_dedent "first line
> second line
> third line")"
first line
second line
third line
Bu komut dosyasını gerçekten kullanmak istiyorsanız, çalıştırılabilir komut dosyasını yolunuzda ~/bin
olacak şekilde taşımak daha mantıklıdır .
Nasıl textwrap.dedent
çalıştığına dair ayrıntılar için python referansına bakın .
Kullanımı $'...'
veya "$(...)"
sizin için kafa karıştırıcıysa, başka bir soru (her yapı için bir tane) sorun. Bulduğunuz / sorduğunuz soruya bir bağlantı sağlamak güzel olabilir, böylece diğer kişilerin bağlantılı bir referansı olur.