Bas komut dosyasında sekme karakterlerini yankılama


313

Bir bash betiği kullanarak bir veya daha fazla sekme karakterini nasıl yankılandırabilirim? Bu kodu çalıştırdığımda

res='       'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

Bunu anladım

res=[ x] # that is [<space>x]

Yanıtlar:


529
echo -e ' \t '

'boşluk sekmesi boşluk satırsonu' yankılanacaktır ( -e'ters eğik çizgi kaçışlarının yorumlanmasını etkinleştir ' anlamına gelir):

$ echo -e ' \t ' | hexdump -C
00000000  20 09 20 0a                                       | . .|

Teşekkürler Johannes. Bu çözümü bulmama yardım ettin: res = '\ t \ t'x; echo -e '[' $ res ']'
09:12

2
Biliyor musun, neden echo -eMakefiles'den çalışmıyor?
dma_k

23
Çünkü echo -ePOSIX değildir ve normalde programın kullanmadığı makeçağrılar /bin/shetkileşimli olarak kullanılır ve normalde -euygulanmaz. Taşınabilirlik için printf '\t'kullanın.
Jo So

Darwin'de (macOS), komutun mansayfası echoseçeneği belirtmiyor -e. Ancak, bu seçenek kabul edilir.
ePi272314

75

Kullan printf, değil echo.

echoKomutun birden fazla farklı sürümü vardır . Orada /bin/echo(olan veya sisteme bağlı olarak, GNU coreutils sürüm olmayabilir) ve echokomut çoğu kabukları içine inşa edilmiştir. Farklı sürümler, kontrol karakterleri için kaçışları belirtmenin veya devre dışı bırakmanın farklı yollarına (veya hiçbir yoluna) sahip değildir.

printfÖte yandan, çok daha az varyasyona sahiptir. Genellikle bir komut olarak var olabilir /bin/printfve bazı kabuklarda yerleşiktir (bash ve zsh var, tcsh ve ksh yok), ancak çeşitli versiyonlar farklı versiyonlarından çok daha benzerdir echo. Ve komut satırı seçeneklerini hatırlamak zorunda değilsiniz (birkaç istisna dışında; GNU Coreutils printf kabul eder --versionve --helpyerleşik bash printf -v varçıktıyı bir değişkende saklamayı kabul eder ).

Örneğiniz için:

res='           'x # res = "\t\tx"
printf '%s\n' "[$res]"

Ve şimdi, benim echode sorduğunuz örnek için de işe yarayacağını kabul etmenin zamanı geldi ; argümanın etrafına çift tırnak koymanız yeterlidir:

echo "[$res]"

kmkaplan'ın yazdığı gibi (iki buçuk yıl önce, fark ettim!). Orijinal komutlarınızla ilgili sorun:

res='           'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

ile değil echo; kabuğun sekmeyi daha önce görmeden bir boşlukla değiştirmesidir echo.

echogibi basit çıktılar için iyidir echo hello world, ancak printfdaha karmaşık bir şey yapmak istediğinizde kullanmalısınız . Sen edebilirsiniz olsun echoişe, ancak çıkan kod farklı bir ile çalıştırdığınızda başarısız olması muhtemeldir echouygulanması ya da farklı bir kabuk.


1
Bunu beğendim, printf bilgisini ve tüm format belirleyicilerini kullanmamı sağlıyor.
Arun

@JezenThomas: Soruyu talep edilenden başka bir şekilde cevapladığı için daha fazla oy verilmiyor. Soru özellikle yankıdan bahseder ve yankı bir fiil değil bir emirdir.
Paulo Neves

@PauloNeves: Soruda bir fiil olarak kullanıldığını söyleyebilirim: " Bir bash betiği kullanarak bir veya daha fazla sekme karakterini nasıl yankılayabilirim ?"
Keith Thompson

34

Dizenizi çift tırnak arasına alın :

echo "[$res]"

1
burada aynı - ilk denediğim bu. -e rağmen iyi çalıştı
froderik

2
@kmkaplan Benim için çalışıyor zsh - benim için başarısız bash
Kal

34

Ayrıca deneyebilirsiniz:

echo Hello$'\t'world.

4
Daha genel çözüm için +1. Bash'ı yıllardır kullanıyorum ve şimdi öğrendim!
Aryeh Leib Taurog

Bu yankı olmadan kullanılabileceği için kabul edilen cevaptan çok daha geneldir.
jwan

22

yankı için -e bayrağı kullanmanız gerekir.

echo -e "\t\t x"

16

Bash man sayfasından:

$ 'String' biçimindeki kelimeler özel olarak ele alınır. Sözcük dizeye genişler, ters eğik çizgiden kaçan karakterler ANSI C standardında belirtildiği gibi değiştirilir.

Böylece bunu yapabilirsiniz:

echo $'hello\tworld'

Bu neden cli üzerinde çalışıyor ama bash betiğinde çalışmıyor?
Freek

13

, Kelimesi kelimesine tuş kullanın ^V( CTRL+V, C-v, ne olursa olsun ).

^VTerminale (veya çoğu Unix editöründe) yazdığınızda , aşağıdaki karakter kelimesi kelimesine alınır . Yankıladığınız bir dizenin içine değişmez sekme karakteri yazmak için bunu kullanabilirsiniz.

Aşağıdaki gibi bir şey çalışır:

echo "^V<tab>"     # CTRL+V, TAB

Bash belgeleri ( qv , "alıntı-insert")

quoted-insert (Cq, Cv) Satır yazdığınız bir sonraki karakteri kelimeye ekleyin. Örneğin, Cq gibi tuş dizileri bu şekilde eklenir.

yan not: buna göre ALT+TAB , aynı şeyi yapmalıyız, ama hepimiz bu diziyi pencere geçişine bağladık, bu yüzden kullanamayız

tab-insert (M-SEKME) Bir sekme karakteri girin.

-

Not: Bu stratejiyi her türlü olağandışı karakterle kullanabilirsiniz. Bir satır başı gibi:

echo "^V^M"        # CTRL+V, CTRL+M

Bunun nedeni, satır başı ASCII 13 ve M alfabenin 13. harfidir, bu nedenle yazdığınızda ^M13. ASCII karakterini alırsınız. ls^MBoş bir komut istemini kullanarak , bir satırbaşı ekleyecek ve istemin dönüşe çarptığınız gibi davranmasına neden olacak şekilde eylemde görebilirsiniz. Bu karakterler normal olarak yorumlandığında, kelimesi kelimesine değişmez karakteri elde etmenizi sağlar.


1
Bunun için size daha fazla oy verebilseydim. Bu durumda argümanlarımda -e kullanmak istemedim ve bu harika çalışıyor. Teşekkürler!
Aaron R.

“... çoğu Unix editörleri”? Bunu hem vi hem de emacs ile girmeye çalıştım ve istenen sonuçları da vermedi.
GreenMatt

Çok güzel! Ve karakter grepiçeren satırları yakalamak için kullanmaya çalışırken günümü kurtardım tab.
Joël

11

Değişkenlerin değerlerini yazdırmak için echo kullanmak yaygın bir Bash tuzaktır. Referans bağlantısı:

http://mywiki.wooledge.org/BashPitfalls#echo_.24foo


Harika, "BashPitfalls", harika bir malzeme parçası ve günlük işlerimden çok acı çekmeyi seviyorum!
Jerry Tian

+1 çünkü bu çok doğru. Ancak kalyanji dizesinin bir “[” ile başladığını ve “\” içermediğini unutmayın.
kmkaplan

2

echo "a\tb"Bir komut dosyasında kullanmak istiyorsanız, komut dosyasını şu şekilde çalıştırırsınız:

# sh -e myscript.sh

Alternatif olarak, myscript.sh dosyasına yürütme izni verebilir ve komut dosyasını çalıştırabilirsiniz.

# chmod +x myscript.sh
# ./myscript.sh

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.