Saya mencoba mencetak dua string yang dipisahkan oleh TAB. Saya telah mencoba:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Keduanya mencetak:
foo bar
Di mana spasi putih di antara keduanya sebenarnya 5 ruang (sesuai memilih output dengan mouse di Putty).
Saya juga telah mencoba menggunakan CTRL + V dan menekan TAB saat mengetik perintah, dengan hasil yang sama.
Apa cara yang benar untuk memaksa tab dicetak sebagai tab, jadi saya dapat memilih output dan menyalinnya ke tempat lain, dengan tab?
Dan pertanyaan kedua: mengapa bash memperluas tab ke spasi?
Pembaruan : Rupanya, ini adalah masalah Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -ruang
bash
putty
whitespace
tabs
Asu
sumber
sumber
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
sebagai tabulator. Jadi, Anda selalu dapat menggabungkan string seperti ini - misalnya sebagai tugas:v='This is'$'\t''a test'
Dan mencetaknya secara harfiah, misalnyaprintf '%s' "$v"
Jawaban:
Seperti kata ilkkachu, ini bukan masalah dengan bash, tetapi dengan emulator terminal yang mengubah tab menjadi spasi pada output.
Memeriksa terminal yang berbeda, dempul, xterm, dan konsole mengubah tab menjadi spasi, sedangkan urxvt dan gnome-terminal tidak. Jadi, solusi lain adalah mengganti terminal.
sumber
stty tab3
.Tidak, tidak. Tidak dalam output
echo
atauprintf
.Ini masalah yang berbeda. Ini bukan tentang shell tetapi terminal emulator, yang mengubah tab menjadi spasi pada output. Banyak, tetapi tidak semuanya melakukannya.
Mungkin lebih mudah untuk mengarahkan ulang output dengan tab ke file, dan menyalinnya dari sana, atau menggunakan
unexpand
output untuk mengkonversi spasi ke tab. (Meskipun itu juga tidak bisa tahu spasi apa itu tab untuk memulai, dan akan mengubahnya semua menjadi tab, jika mungkin.) Ini tentu saja tergantung pada apa, tepatnya, yang perlu Anda lakukan dengan output.sumber
Dalam
printf '%s\t%s\n' foo bar
,printf
apakah outputfoo<TAB>bar<LF>
.f
,o
,b
,a
Danr
karakter grafis single-lebar.Setelah menerima karakter-karakter itu, terminal akan menampilkan mesin terbang yang sesuai dan memindahkan kursor satu kolom ke kanan, kecuali itu sudah mencapai tepi kanan layar (kertas di mesin ketik tel-asli)), dalam hal ini mungkin memberi makan garis dan kembali ke tepi kiri layar (bungkus) atau hanya membuang karakter tergantung pada terminal dan bagaimana itu dikonfigurasi.
<Tab>
dan<LF>
dua karakter kontrol .<LF>
(alias baris baru) adalah pembatas baris dalam teks Unix, tetapi untuk terminal, itu hanya memberi makan garis (pindahkan kursor satu posisi ke bawah). Jadi driver terminal di kernel akan benar-benar menerjemahkannya<CR>
(kembali ke tepi kiri layar),<LF>
(kursor ke bawah) (stty onlcr
umumnya aktif secara default).<Tab>
memberitahu terminal untuk memindahkan kursor ke perhentian tab berikutnya (yang pada kebanyakan terminal terpisah 8 posisi secara default tetapi juga dapat dikonfigurasi untuk diatur di mana saja) tanpa mengisi celah dengan kosong.Jadi, jika karakter-karakter tersebut dikirim ke terminal dengan tab berhenti setiap 8 kolom sementara kursor berada di awal baris kosong, itu akan menghasilkan:
dicetak pada layar di garis itu. Jika dikirim saat kursor berada di posisi ketiga dalam baris yang berisi
xxxxyyyyzzzz
, itu akan menghasilkan:Pada terminal yang tidak mendukung tabulasi, driver terminal dapat dikonfigurasi untuk menerjemahkan tab tersebut ke urutan spasi. (
stty tab3
).Karakter SPC, dalam mesin ketik tele asli akan memindahkan kursor ke kanan, sedangkan backspace (
\b
) akan memindahkannya ke kiri. Sekarang di terminal modern, SPC bergerak ke kanan dan juga menghapus (menulis karakter ruang seperti yang Anda harapkan). Jadi liontin\b
harus menjadi sesuatu yang lebih baru daripada ASCII. Pada kebanyakan terminal modern, itu sebenarnya urutan karakter:<Esc>
,[
,C
.Ada lebih banyak urutan pelarian untuk memindahkan
n
karakter ke kiri, kanan, atas, bawah atau pada posisi apa pun di layar. Ada urutan pelarian lain untuk menghapus (mengisi dengan kosong) bagian dari garis atau wilayah layar, dll.Urutan mereka biasanya digunakan oleh aplikasi visual yang seperti
vi
,lynx
,mutt
,dialog
di mana teks ditulis pada posisi yang sewenang-wenang di layar.Sekarang, semua emulator terminal X11 dan beberapa yang bukan X11 lainnya seperti GNU
screen
memungkinkan Anda memilih area layar untuk menempelkan salinan. Saat Anda memilih bagian dari apa yang Anda lihat divi
editor, Anda tidak ingin menyalin semua urutan pelarian yang telah digunakan untuk menghasilkan output itu. Anda ingin memilih teks yang Anda lihat di sana.Misalnya jika Anda menjalankan:
Yang mensimulasikan sesi editor tempat Anda masuk
abC
, kembali ke awal, gantiab
denganAC
,C
denganB
, pindah ke perhentian tab berikutnya, lalu satu kolom lagi ke kanan, lalu dua kolom ke kiri, lalu masukD
.Kamu melihat:
Itu adalah,,
ABC
celah 4 kolom danD
.Jika Anda memilihnya dengan mouse
xterm
atauputty
, mereka akan menyimpan dalam seleksiABC
, 4 karakter spasi danD
, tidakabC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.Apa yang berakhir dalam pemilihan adalah apa yang telah dikirim oleh
printf
tetapi setelah diproses oleh driver terminal dan terminal emulator.Untuk jenis transformasi lain, lihat
<U+0065><U+0301>
(e
diikuti oleh aksen akut kombinasi) yang diubah menjadi<U+00E9>
(é
bentuk yang sudah dibuat sebelumnya) olehxterm
.Atau
echo abc
yang akhirnya diterjemahkanABC
oleh pengemudi terminal sebelum dikirim ke terminal setelah astty olcuc
.Sekarang,,
<Tab>
like<LF>
adalah salah satu dari beberapa karakter kontrol yang sebenarnya kadang-kadang ditemukan dalam file teks (juga<CR>
dalam file teks MSDOS, dan kadang<FF>
- kadang untuk page break).Jadi beberapa emulator terminal memilih untuk menyalinnya bila mungkin di copy-paste buffer untuk menjaga mereka (yang umumnya tidak kasus
<CR>
atau<LF>
meskipun).Misalnya, di terminal berbasis VTE seperti
gnome-terminal
, Anda mungkin melihat bahwa, ketika Anda memilih outputprintf 'a\tb\n'
pada saluran kosong,gnome-terminal
sebenarnya menyimpana\tb
dalam pemilihan X11, bukannyaa
7 spasi danb
.Tapi untuk output
printf 'a\t\bb\n'
, itu tokoa
, 6 ruang danb
, dan untukprintf 'a\r\tb\n'
,a
, 7 ruang danb
.Ada kasus lain di mana terminal akan mencoba untuk menyalin input yang sebenarnya, seperti ketika Anda memilih dua baris setelah berjalan di
printf 'a \nb\n'
mana ruang trailing yang tidak terlihat itu akan dipertahankan. Atau ketika memilih dua garis tidak termasuk karakter LF ketika dua garis hasil dari pembungkus di margin yang tepat.Sekarang, jika Anda ingin menyimpan output
printf
ke dalam pilihan CLIPBOARDX11
, yang terbaik adalah melakukannya secara langsung seperti dengan:Perhatikan bahwa ketika Anda menempelkannya di
xterm
atau sebagian besar terminal lainnya,xterm
sebenarnya menggantikannya\n
dengan\r
karena itulah karakter yangxterm
dikirim ketika Anda menekan Enter(dan driver terminal dapat menerjemahkannya kembali ke\n
).sumber
X11
adalah yang menangani pemilihan salin-tempel di emulator terminal sepertixterm
atauputty
di Unix. Emulator terminal lain mungkin memiliki mekanisme copy-paste dan cara untuk menyimpan konten sewenang-wenang di sana, seperti perintahreadbuf
danregister
di layar GNU.