Ünite ayırıcı (ASCII 31) terminal çıkışında neden görünmez?


17

Birim ayırıcı ASCII karakteri (ASCII 31, sekizli 37), Vim'de a ^_. Ancak aynı dosyayı terminale yazdırırsam karakter görünmez olur. Bu, bir satırdaki alanların birbirine yapışmasına neden olur:

# In Vim and less:

first field^_second field^_last field

# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field

# print 2nd field with awk 
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field

Sanırım birim ayırıcıyı cat -v ile görünür yapabilirim:

cat -v delim.txt
first field^_second field^_last field

Ama bu oldukça hantal. Bash kabuğunda stdout'a yazdırıldığında birim ayırıcı neden görünür bir temsile sahip değil? Kabuk çıktısını doğru şekilde kopyalayıp yapıştıramıyorum; birim ayırıcı işlem sırasında kaybolur.


Tüm karakterler yazdırılamaz, birim ayırıcı bunlardan biridir. Bazı editörler, düzenlemeyi mümkün kılmak için bir şekilde görüntüler. Belirsizliği azaltmak için bir dizi yazdırılabilir karaktere ve belki de farklı bir yazı tipine / renge çevirmeniz gerekir.
ctrl-alt-delor

3
31 ve 127'nin altındaki ASCII kodları, bir terminalin veya cihazın bir şey yapmasına (bu yüzden neden kontrol kodları olarak adlandırılır) veya bir şey görüntülemek yerine bir protokolde (EOT veya SOH gibi) bir şeye neden olmasını amaçlamaktadır. Terminaller daktilo benzeri cihazlar olduğunda geri gider ve teletype'ın satırbaşına dönüşü gibi şeyler fiziksel olarak gerekliydi. Editörler, bir şeyi düzenlediğiniz ve kontrol kodlarının ne istediğini yapmak için terminal oluşturmak istemediğiniz için bunları "^" gösterimini kullanarak oluşturmayı seçebilir.
LawrenceC

1
@LawrenceC: Kod 127 aslında bir terminalin hiçbir şey yapmamasına neden olmayı amaçladı , biri bir kaseti yumrukladıysa ve bir hata yaptıysa, kaseti bir boşlukla yedeklemek ve "ovuşturmak" a basarsa, hepsini yumruklamak için sekiz delik. Okuyucu tüm deliklerle delinmiş karakterle karşılaştığında, onu tel üzerinden gönderir, ancak alıcı onu görmezden gelebilir.
supercat

Yanıtlar:


19

Birim ayırıcı ( USolarak da bilinir) karakteri IS1, içinde cntrlkarakteri ile olduğu değil de printkarakter sınıfı. Bu bilgileri kullanmak üzere tasarlanmış programlar için , metni gruplar halinde düzenlemeyi amaçlayan bir kontrol karakteridir . Genel olarak, yazdırılamayan karakterler muhtemelen farklı programlarda veya ortamlarda farklı şekilde yorumlanacak ve görüntülenecektir.

^_Vim'de temsil edildiğini görmenizin nedeni , Vim'in etkileşimli bir editör olmasıdır. Doğru ikili karakter diske yazıldığı sürece, yazdırılamayan karakterleri istediği gibi serbestçe oluşturabilir.

Kabukta aynı davranışı elde edemezsiniz, çünkü Unix kabuk programları çalışacak ve düz metinleri birbirine geçirecek şekilde yazılmıştır. Bir catdosya oluşturduğunuzda, terminale yazılan metin dosyada gerçekte olan metin olmalıdır.

Böylece karakteri yorumlamak için terminal cihazına bırakır. Ve bazı terminal emülatörleri çıkıyor do hale USdiğerlerinden farklı bir karakter. Olarak gnome-terminal(ya da herhangi bir vtemerkezli terminali), karakter hex kodunu ihtiva eden bir kutu olarak işlenecek 001F. Gelen xtermveya rxvtkarakter aslında görünmez.


Eh ben söyleyemem USolduğunu tamamen görünmez. Bu karakteri Ctrl+/(üzerinden onaylandı <C-v><C-/>) ile bir terminale eklediğimde , satırdaki öngörülemeyen miktarda metni siler. Davranışını tam olarak anlamıyorum, ancak bir dizi boşluk eklemek yerine, bir dizi karakteri sildiği, ancak bazen rastgele metin eklediği için bir çeşit "ters sekme" etkisi var gibi görünüyor, bu yüzden kafa karıştırıcı .
Braden Best

10

Birim ayırıcı ASCII Kontrol Karakterleri aralığındadır ve bu nedenle görsel bir temsili yoktur (veya olmamalıdır).

Vim ve diğer bazı editörler bunları görüntüler, böylece onları düzenleyebilirsiniz. Fark ettiğiniz gibi, cat -vbunu da görüntüler. Man sayfası, yazdırılmayan karakterlerin, dosyanın orijinal içeriği olmayan ve bu nedenle çıktı aslında başka bir program içinse sorun yaratabilecek yazdırılabilir bir temsil ile değiştirilmesine neden olan -vkısa biçimini gösterir. --show-nonprinting.

Gördüğünüz gösterim, bunun bir kontrol karakteri olduğunu ima eder: a ile eklenmiş bir karakter, + karakterine ^yönelik ortak bir gösterimdir Ctrl; bu, terminalde bu karakteri üreten anahtar birleşimdir. Ctrl+ _, örneğin birim ayırıcıyı vim olarak girmenizi sağlar. Ancak başka bir düzenleyici veya bazı GUI görüntüleyici onaltılı kodu, bir yer tutucuyu veya tamamen farklı bir şey görüntüleyebilir.

Terminaliniz kontrol karakterlerini yazdırmadığından, metin seçildiğinde de kopyalanmaz (newline ve sekme gibi boşluk karakterleri burada da kontrol karakterleri olan bir istisnadır). Terminalde, kopyalama sırasında genellikle yok sayılan başka bir kontrol karakteri örneği ESC, metni renklendirme kodunun ardından gelen bir karakter olan renk kodlarıdır .

Terminalinizdeki karakterleri göstermek için, birim ayırıcıyı yazdırılabilir bir karakterle değiştiren bir program kullanmaktan başka bir yol yoktur.


3

Biraz diğer (çok iyi) cevapların sınırında , dosya içeriğini görüntülerken sadece kontrol karakterini değiştirmek ^_istiyorsanız , yardımcı programı (ve biraz bash uyumlu sözdizimini) kullanarak harf çevirmek isteyebilirsiniz tr:

# Replace the control character US (^_) by *one* other character
$ cat my.file | tr $'\c_' ':'

Bu kontrol karakterini "genişletilmiş" formuyla değiştirmeniz gerekirse, sedbunun yerine ihtiyacınız olacaktır :

# Replace the control character US (^_) by any string
cat /tmp/f | sed s/$'\c_'/^_/g

Lütfen sözdizimini not edin $'\cX': bu sözdizimi (bash uyumlu kabuk) ilgili kontrol karakterini değiştirmeyi bildirir. "Düzeltme işareti" ni kullanarak kontrol karakter takma adı listesi için wikipedia'ya bakın . Bu sözdizimini beğenmediyseniz, sekizli $'\037'veya onaltılı $'\x1f'gösterimi kullanmayı tercih edebilirsiniz.

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.