Ubah ukuran tab dari perintah "cat"

15

Ketika saya berada di vimsaya bisa mengubah ukuran tab dengan perintah berikut:

:set ts=4

Apakah mungkin untuk mengatur ukuran tab untuk catoutput perintah juga?

Meysam
sumber

Jawaban:

21

Perintah pertama di sini mengemulasi format yang Anda lihat vim. Secara cerdas memperluas tab ke jumlah ruang yang setara, berdasarkan pengaturan tab-STOP (ts) dari setiap 4 kolom.

printf "ab\tcd\tde\n" |expand -t4   

Keluaran

ab  cd  de

Untuk menjaga tab sebagai tab dan mengatur posisi STOP untuk setiap kolom ke-4, maka Anda harus mengubah cara lingkungan bekerja dengan tab-char (seperti halnya vim dengan :set ts=4perintah)

Misalnya, di terminal, Anda dapat mengatur tab STOP ke 4 dengan perintah ini;

tabs 4; printf "ab\tcd\tde\n" 

Keluaran

ab  cd  de
Peter.O
sumber
senang mengetahui (1). expand(dari paket coreutils) dan tabs(dari paket ncurses) perintah, (2). dan arti dari ts adalah [ T ] ab [ S ] top
LiuYan 刘 研
10

Cukup gunakan kode berikut:

tabs -n

Di mana n adalah jumlah spasi yang Anda inginkan untuk berhubungan dengan tab juga. Agar tidak harus melakukan ini setiap kali Anda memulai shell, hanya mengedit Anda .bash_profiledi ~/dan menambahkan baris di atas ke akhir file.

Untuk info lebih lanjut tentang perintah tab, lihat:

man tabs
Gustavo Bezerra
sumber
2
Berhati-hatilah bahwa mengubah lebar tab default secara permanen mungkin mengacaukan perintah lain (misalnya lsput out mungkin terlihat tidak selaras dengan benar).
Gustavo Bezerra
9

Tidak ada gagasan tentang tab atau berhenti di tab cat; program hanya menyalurkan input ke output dan memperlakukan tab seperti karakter lainnya. Jika perangkat output kebetulan merupakan terminal, tab akan ditangani sesuai dengan perilaku terminal yang dikonfigurasi untuk menyediakan.

Sistem yang mengimplementasikan POSIX.1 memiliki perintah yang disebut tabs(1)yang akan menyesuaikan konsep terminal tentang bagaimana tab harus ditampilkan. Tergantung pada tata letak tab tertentu tidak dianggap sebagai ide yang baik, karena seseorang dapat mengirim file Anda ke beberapa perangkat lain seperti printer yang tidak akan melakukan apa yang Anda inginkan.

Ketika Anda menyesuaikan tsdi vim(atau polos vi), semua yang Anda lakukan adalah menyesuaikan bagaimana editor menafsirkan karakter tab ketika ditampilkan. Tidak ada hubungannya dengan apa yang berakhir di file.

Blrfl
sumber
Terima kasih untuk penjelasannya Bagaimana printer dikonfigurasikan untuk merawat tab?
Meysam
Sebagian besar printer memperlakukannya dengan cara yang sama seperti kebanyakan terminal lakukan secara default: margin kiri dan setiap delapan karakter sesudahnya.
Blrfl
5

Berdasarkan jawaban dan contoh di atas, tampaknya perintah aktual yang diinginkan OP adalah ...

cat somefile | expand -t4

Ini bekerja untuk saya di Red Hat 6.4.

ScotlynHatt
sumber
2

Untuk memperluas jawaban yang sudah diberikan, expanddapat juga mengambil daftar posisi berhenti tab. Ini berguna jika panjang konten kolom beragam bervariasi.

Saya memenuhi persyaratan ini hari ini ketika saya ingin membuat hasil yang openssl cipherslebih mudah dibaca:

$ openssl ciphers -v 'HIGH'|tr -s ' ' '\t'|expand -t31,41,57,70,90
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2   Kx=ECDH         Au=RSA       Enc=AESGCM(256)     Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2   Kx=ECDH         Au=ECDSA     Enc=AESGCM(256)     Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2   Kx=ECDH         Au=RSA       Enc=AES(256)        Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2   Kx=ECDH         Au=ECDSA     Enc=AES(256)        Mac=SHA384
...
ECDH-ECDSA-AES128-SHA          SSLv3     Kx=ECDH/ECDSA   Au=ECDH      Enc=AES(128)        Mac=SHA1
AES128-GCM-SHA256              TLSv1.2   Kx=RSA          Au=RSA       Enc=AESGCM(128)     Mac=AEAD
AES128-SHA256                  TLSv1.2   Kx=RSA          Au=RSA       Enc=AES(128)        Mac=SHA256
AES128-SHA                     SSLv3     Kx=RSA          Au=RSA       Enc=AES(128)        Mac=SHA1

CAMELLIA128-SHA                SSLv3     Kx=RSA          Au=RSA       Enc=Camellia(128)   Mac=SHA1
PSK-AES128-CBC-SHA             SSLv3     Kx=PSK          Au=PSK       Enc=AES(128)        Mac=SHA1

Menggunakan hanya expand -t31akan meledakkan lebar output dari sekitar 100 karakter menjadi lebih dari 160 karakter.

Alexander Stumpf
sumber
1
Cara yang lebih mudah untuk melakukannya adalah dengan menggunakan column:openssl ciphers -v 'HIGH' | column -t
muru
0

Banyak terminal mendukung pengaturan variabel berhenti tab. Mereka yang vt100, linux dan atau mendukung standar EMCA-48 lakukan, sebagian besar istilah pada pengaturan dukungan linux ukuran tab: xterm dan keluarga (uxterm, urxvt) xfce4-terminal, luit, Terminal, SecureTTY, antara lain.

Jadi menulis skrip beberapa tahun yang lalu untuk mengatur tab saya saat login ke setiap 2 spasi - dulu menggunakan 4, lalu 3 untuk sedikit pendek, dan sekarang pada 2 ....

Jadi sekarang, jika saya 'menyimpan' file, tab dalam file tersebut akan meluas ke pengaturan terminal saya.

Jika saya melewati vim atau lebih, mereka melakukan ekspansi tab sendiri, tetapi banyak utilitas menggunakan tab.

Akan menyertakan skrip di sini untuk referensi, dan atau penggunaan pribadi:

#!/bin/bash  -u
#console_codes(4) man page... vt100/2 et && EMCA-48 standard
# (c) la walsh (2013) -- free to use and modify for personal use.
#                     -- optionally licenced under Gnu v3 license.

# v0.0.3    - try to reduce tabcols to minimal set to reproduce.
# v0.0.2    - set tabs for full terminal width (try to get term width)

shopt -s expand_aliases extglob
alias my=declare        
alias int='my -i'       array='my -a' intArray='my -ia'   string=my

my _Pt=$(type -t P)
[[ $_Pt && $_Pt == function ]] && unset -f P
alias P=printf
unset _Pt

P -v clrallts  "\x1b[3g"    #Clear All TabStops
P -v hts       "\033H"      #Horizontal TabStop
P -v cpr       "\x1b[6n"    #Current Position Report


getcols() {                 # try to read terminal width
  local sttyout="$(stty size </dev/tty)"
  int default_cols=80
  if [[ -n ${COLUMNS:-""} && $COLUMNS =~ ^[0-9]+$ ]]; then 
    default_cols=$COLUMNS; fi
  [[ -z ${sttyout:-""} ]] && { echo $default_cols; return 0; } 
  int cols="${sttyout#*\ }"
  echo -n $[cols<2?default_cols:cols]
  return 0
}

getpos () {
  string ans    wanted=${1:-xy}
  int attempt=0 max_attempt=1   # in case of rare failure case
                                # use 'attempt' value as additional
                                # time to wait for response
  while : ; do
    ( ( P "\x1b[6n" >/dev/tty) & 2>/dev/null )  
    read  -sd R -r -t $[2 + attempt] ans </dev/tty; 
    ans=${ans:2}; 
    int x=0-1 y=0-1
    if ! x="${ans#*;}" y="${ans%;*}" 2>/dev/null  || 
      ((x==-1||y==-1)); then
      ((attempt+=1 < max_attempt)) && continue
    fi
  break; done
  string out=""
  [[ $wanted =~ x ]] && out="$x"
  [[ $wanted =~ y ]] && out="${out:+$x }$y"
  [[ $out ]] && echo -n "$out"
}

declare -ia tabs


get_tabs () {
  P "\r"
  tabs=()
  int pos=0 oldpos=0-1
  while ((oldpos!=pos));do
    ((pos)) && tabs+=($pos)
    oldpos=pos
    P "\t"
    pos=$(getpos x)
  done
  P "\r"
  return 0
}

# Note: this func uses ability to _read_ tabstops as _proxy_ for setting them
# (i.e. it makes no sense to be able to read them if you can't set them)

test_tabset_ability () {
  string prompt="tty_tab:"
  int newcol=${#prompt}+1
  P "\r$prompt"
  int mycol=$(getpos x)
  ((mycol && mycol==newcol)) && return 0    ## return OK

  { P " Term tabset ability not detected mycol=${mycol:-''},"
    P " promptlen=$newcol)\n"; } >&2
  exit -1 
}

do_help_n_display_curtabs () {
  P " <n>   - set tab stop to N\r"
  intArray diffs;
  int last=1  cur i
  string eol=""
  get_tabs && {
    for ((i=0; i<${#tabs[@]}; ++i)); do
      cur=${tabs[i]}
      diffs[i]=cur-last
      last=cur
    done
    intArray reverse_tabs_set=()
    int prevtab=0-1
    for ((i=${#diffs[@]}-2; i>0; --i)); do
      int thistab=${diffs[i]}
      if ((thistab!= prevtab)) ;then 
        reverse_tabs_set+=($thistab)
        prevtab=thistab
      fi
    done
    P "current value: tty_tab "
      for ((i=${#reverse_tabs_set[@]}-1; i>=0; --i)); do
        P "%d " "${reverse_tabs_set[i]}"; done
    P "\r";
  }
  get_tabs  && {
    P "(from 1, tabs skip to column: "
    P "%s " "${tabs[@]}"
    P "\r\n"
  }
}

set_tabs () {
  int max_col=${1:=0-80}
  int tabstop=${2:-?"need a param for tabstop"}
  int tab=$tabstop        pos=0
  string str=""
  P $clrallts               ## reset old tabs
  while ((++pos<cols)) ;do  ## move across screen setting tabs
    str+=" "
    ((pos%tab)) || str+="$hts"
  done
  P "\r$str\r"
}


int cols=$(getcols)

test_tabset_ability         ## exits if no ability


if (($#==0)) ; then
  do_help_n_display_curtabs
  exit 1
else
  set_tabs "$cols" "$@"
fi

# vim: ts=2 sw=2

Semoga ini bisa membantu ...

Astara
sumber
-2

Menurut halaman manual, kucing tidak bisa melakukannya sendiri. Tetapi Anda dapat misalnya menjalankan output dari cat through trfilter untuk mengganti tab dengan sejumlah ruang yang Anda inginkan:

cat somefile | tr '\t' '  '

akan mengganti karakter tab dengan dua spasi.

Perbarui: seperti yang ditunjukkan dalam komentar untuk posting ini, ini sebenarnya tidak berfungsi. Meskipun demikian, saya menyimpan jawabannya sebagai contoh bagaimana tidak melakukannya.

Petr Uzel
sumber
3
Ini sebenarnya menggantikan '\t'dengan hanya satu ruang, tidak peduli berapa banyak ruang di antara pasangan kutipan kedua' '
Meysam
3
trtidak bekerja seperti itu .. setiap byte dari arg 1 diganti oleh masing-masing byte yang sesuai dari arg 2 ..... Oleh karena itu printf '\t' |tr '\t' 'ळ' mencetak byte tunggal yang nilai hex-nya adalah \xE0.. yang merupakan byte pertama dari tiga UTF-8 byte yang dikodekan yang membentuk karakter (yang nilai Unicode CodePointnya adalah U + 0933)
Peter.O
Ah, tentu saja. Terima kasih telah menangkap kesalahan konyol saya!
Petr Uzel