Yankı-e'nin tersi nedir?


13

Yazdırılamayan karakterler, yeni satırlar veya sekmeler içeren bir dizem varsa, echobu dizeyi yazdırmak ve bu karakterler için kodları göstermek için kullanabileceğim bir yol var mı (örneğin, \nyeni satır \biçin, geri alan için)?


2
printf komutunu kullanabilirsiniz, bkz. man printf
PersianGulf

12
e- ohce* rimshot *
David Richerby

3
printf '%q' "$str"kaçan dize yazdırılır. Bunu bir cevap olarak eklemiyorum, çünkü aynı echo -ekullanan kaçış biçimi değil - bunun yerine eval-güvenli olması amaçlanıyor - ancak (1) hedefiniz insan tarafından okunabilirlik ise, yeterince iyi, (2) hedefiniz güvenli kabuk oluşturma ve (3) echo -eKötü ve Yanlış ise yeterince iyi (POSIX spesifikasyonunu okursanız, printf'in dize biçimlendirmesi için tercih edilen yol olduğunu ve echo -eadresindeki POSIX tarafından garanti edilmediğini göreceksiniz herşey).
Charles Duffy

Yanıtlar:


7

Bunu yapmanın birçok yolu var. Bildiğim en taşınabilir ikisi sedve odikisi de POSIX.

printf '\n\r\b\t\033[01;31m' | sed -n l

Bu ... readtarzı kaçar - C tarzı.

ÇIKTI

$
\r\b\t\033[01;31m$

od biraz daha yapılandırılabilir ...

printf '\n\r\b\t\033[01;31m' |
od -v -w12 -t c -t a -A n

 \n  \r  \b  \t 033   [   0   1   ;   3   1   m
 nl  cr  bs  ht esc   [   0   1   ;   3   1   m

Tüm bu seçeneklerin neler olduğunu bilmek istiyorsanız man od, ancak iki tür kaçış istediğimi belirtiyorum - -t cters eğik çizgi kaçıyor ve -t aadlandırılmış karakterler. -wYukarıda kullanılan seçenek POSIX belirtilmedi.

Ve işte, her bir baytın sekizlik değerlerini argümanlarında portatif olarak basacak küçük bir kabuk işlevi - elbette, odaşağıdakilerle de başa çıkabilir -t o:

proctal() (LC_ALL=C
    for a do while [ -n "$a" ] 
    do printf %o\\n "'$a"
    a=${a#?}; done; done)  

Bu basit bir soru. Bu biraz daha karmaşık. Bununla birlikte, kabuğa özgü printf -quygulamaların neler yapabileceğini yapabilmelidir .

bsq() (set -f; export LC_ALL=C IFS=\'
    for a do q=${a##*\'}; printf \'
    [ -n "${a#"$q"}" ] &&
        printf "%s'\''" ${a%\'*}
    printf "%s'\n'''''\n" "$q"; done |
    sed -n "/'''''"'/!H;1h;//!d;$!n;x;l' |
    sed -e :n -e '/\\$/N;s/.\n//;tn
        s/\([^\\]\\\(\\\\\)*\)\([0-9]\)/\10\3/g
        s/\\\\'"''/\\\\''"'/g;s/$$//'
)

Biraz ek ile daha önce gelen örnek dizeyi kullanmak:

bsq "$(printf '\n\r\'\''b\t\033[01;31m')"

ÇIKTI

'\n\r\\'\''b\t\0033[01;31m'

Sadece biraz farklı. Fazladan 0ve fazladan bir \bters eğik çizgi olduğunu fark edebilirsiniz. Bu, bir readveya %b printfbağımsız değişkene kolay çeviri yapılmasını sağlamak içindir . Örneğin:

i=0
until [ $((i=$i+1)) -gt 5 ]
do touch "\%$i$(printf 'hey\b \t;\n\033 ')"
done   #just for ugly's sake

bsq * | eval "
    printf '<%b>\n' $(tr \\n \ )
" | tee /dev/fd/2 |
sed -n l

ÇIKTI

<\%1he  ;
>
<\%2he  ;
>
<\%3he  ;
>
<\%4he  ;
>
<\%5he  ;
>
<\\%1hey\b \t;$
\033 >$
<\\%2hey\b \t;$
\033 >$
<\\%3hey\b \t;$
\033 >$
<\\%4hey\b \t;$
\033 >$
<\\%5hey\b \t;$
\033 >$

@ StéphaneChazelas Hala sadece tek baytlık grafikler yapacak, ancak umarım şimdi berbat olma ihtimali daha düşüktür.
mikeserv

1
Seni 10k işaretine
Ramesh

Woohoo !!!!!!!!!
slm

@slm - tahmin edeyim .. Gerçekten proctalsevdiniz mi?
mikeserv

@ StéphaneChazelas - üzerinde düşüncelerin var mı bsq()- bir şey eksik mi? Soruyorum çünkü ters eğik çizgilerden tamamen emin değilim.
mikeserv

12

Eğer kaldırdığınızda -egeçiş echoiçinde, bashve sunulan xpg_echoaktif edilmedi seçeneği, onların orijinal metnin başka bir şey olarak dizeleri yazdırmak gerekir. Yani \nve \tolarak tam anlamıyla o kadar gösterecektir.

Misal

$ echo "hi\t\tbye\n\n"
hi\t\tbye\n\n

$ echo -e "hi\t\tbye\n\n"
hi      bye

Ayrıca kullanabilirsiniz printfyerleşik komutu ksh93, zshveya bashda bu finagle.

$ printf "%q\n" "$(echo -e "hi\t\tbye\n\nbye")"
$'hi\t\tbye\n\nbye'

( bashçıktı yukarıda gösterilmiştir. Kabuğa bağlı olarak bazı varyasyonlar vardır).

alıntı gelenhelp printf içindebash

%q bağımsız değişkeni kabuk girdisi olarak yeniden kullanılabilecek şekilde alıntılayın


1
O değil printf %qen sondaki kesilmesi olduğunu \ns, bu kadar $()onları dışarı şeritler çıkış yakalama.
ecatmur

@ecatmur - teşekkürler bunu gece geç saatlerde yazdım ve daha fazla hata ayıklamaya çalışmadım. Doğru olursunuz, onları sıyırmış olan alt kabuk. Nedeni: unix.stackexchange.com/questions/17747/…
slm

... her neyse, printfçıktısını yakalamak için bir alt kabuğun içinde koşmak saçmadır, çünkü printf -v varnameçıktıyı doğrudan bir değişkene koyacaktır, alt kabuk dahil değildir.
Charles Duffy

@CharlesDuffy - Seni takip etmiyorum printf, bir alt kabukta koşmuyorum , bir tanesinde koşuyordum echo, sadece özel karakter çıktısını echoalıp kaçan nota dönüştürebildiğini göstermek için.
slm

@slm, bu ilk açıklamaya bir yanıttı (ilk yorumun yanıtladığı kod), şimdi bulduğum kod değil. Önceki düzenleme durumu hakkında yanlış bir şey çıkardığımda özür dilerim.
Charles Duffy

5

Gibi bir şey kullanabilirsiniz,

$ cat filename
Ramesh is testing
New Line        is

Şimdi şöyle bir şey yapabilirsiniz,

$ cat -A filename

Çıktı

Ramesh is testing$
New Line ^Iis $

Dosyasız başka bir genel test,

$ echo Hello$'\t'world. | cat -A

Yukarıdaki komut çıktıyı şu şekilde verir:

Hello^Iworld.$

Referanslar


4
Ya da GNU olmayan kedi uygulamalarında, örneğin MacOS / X, kedinizi veterinere götürün
tink

3

İle zshvardır (q), (qq), (qqq), (qqqq)olabilir değişken genişleme bayrakları alıntı çeşitli şekillerde değişkenleri:

$ a=$'a b\nba\bc\u00e9\0'

$ printf '%s\n' $a
a b
bcé

$ printf %s $a | od -vtc
0000000   a       b  \n   b   a  \b   c 303 251  \0
0000013

$ printf '%s\n' ${(q)a}
a\ b$'\n'ba$'\b'cé$'\0'

$ printf '%s\n' ${(qq)a}
'a b
bcé'

$ printf '%s\n' ${(qqq)a}
"a b
bcé"

$ printf '%s\n' ${(qqqq)a}
$'a b\nba\bcé\0'

$ (){local LC_ALL=C; print -r -- ${(qqqq)a}}
$'a b\nba\bc\303\251\0'

Sizin durumunuzda, muhtemelen son ikisinden birini isteyeceksiniz.


1

od -cnormal karakterleri normal şekilde basar, ancak özel karakterler (sekme, yeni satır, vb.) ve yazdırılamayan karakterler printfçıkış kodu olarak yazdırılır .

Yani:

$ echo -e asdf\\nghjk\\003foo | od -c -An
   a   s   d   f  \n   g   h   j   k 003   f   o   o  \n

-AnSöyler oddeğil çıkış adresini etmek.


-1

printfKomutu kullanın . Örneğin:

printf "Hello\nthis is my line

çıktı olacak

Hello
this is my line

1
Bu aynı şekilde echo -earadığım, ters .
drs

bana özel bir örnek verebilir misin?
Lazuardi N Putra
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.