Zmień rozmiar tabulatora polecenia „cat”


15

Kiedy jestem w vimśrodku, mogę zmienić rozmiar tabulatora za pomocą następującego polecenia:

:set ts=4

Czy można również ustawić rozmiar tabulacji dla catdanych wyjściowych polecenia?

Odpowiedzi:


21

Pierwsze polecenie tutaj emuluje formatowanie, w którym widzisz vim. Inteligentnie rozwija tabulatory do równoważnej liczby spacji, w oparciu o ustawienie tab-STOP (ts) co 4 kolumny.

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

Wynik

ab  cd  de

Aby zachować tabulatory jako tabulatory i ustawić tab STOP pozycje w każdej czwartej kolumnie, musisz zmienić sposób działania środowiska za pomocą tab-char (tak jak vim robi to z :set ts=4poleceniem)

Na przykład w terminalu możesz ustawić zakładkę STOP na 4 za pomocą tego polecenia;

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

Wynik

ab  cd  de

dobrze wiedzieć (1). expand(z pakietu coreutils) i tabs(z pakietu ncurses), (2). a znaczenie ts to [ T ] ab [ S ] top
LiuYan 刘 研

10

Wystarczy użyć następującego kodu:

tabs -n

Gdzie n jest liczbą spacji, które również mają być zgodne z tabulatorami. W celu nie trzeba robić to przy każdym uruchomieniu powłoki, wystarczy zmienić swój .bash_profilein ~/i dodać powyższy wiersz na końcu pliku.

Aby uzyskać więcej informacji na temat polecenia tabs, patrz:

man tabs

2
Tylko uważaj, że trwała zmiana domyślnej szerokości zakładek może zepsuć inne polecenia (na przykład lsout put może wyglądać nieprawidłowo wyrównany).
Gustavo Bezerra

9

Nie ma pojęcia o tabulatorach ani o ogranicznikach tabulacji cat; program po prostu wprowadza dane wejściowe do wyjścia i traktuje tabulatory jak każdy inny znak. Jeśli urządzeniem wyjściowym jest terminal, karty będą obsługiwane zgodnie z tym, jakie zachowanie skonfigurowano w terminalu.

Systemy implementujące POSIX.1 mają wywołane polecenie tabs(1), które dostosuje koncepcję terminala, w jaki sposób powinny być wyświetlane tabulatory. W zależności od konkretnego układu zakładek nie jest to dobry pomysł, ponieważ ktoś może wysłać plik na inne urządzenie, takie jak drukarka, która nie zrobi tego, co zamierzałeś.

Podczas regulacji tsw vim(lub zwykły vi), wszystko co robisz jest dostosowanie w jaki sposób interpretuje Editor tabulatorów kiedy wyświetlany. Nie ma to wpływu na to, co znajdzie się w pliku.


Dzięki za wyjaśnienie. Jak drukarka jest skonfigurowana do obsługi kart?
Meysam

Większość drukarek traktuje je w ten sam sposób, co większość terminali: domyślnie lewy margines, a następnie co osiem znaków.
Blrfl

5

W oparciu o powyższe odpowiedzi i przykłady wydaje się, że faktyczne polecenie, jakiego chciał PO, to ...

cat somefile | expand -t4

Działa to dla mnie w Red Hat 6.4.


2

Aby rozwinąć już udzielone odpowiedzi, expandmożesz również wziąć listę pozycji tabulacji. Jest to przydatne, jeśli długości treści różnych kolumn są bardzo różne.

Przekonałem się o tym dzisiaj, kiedy chciałem, aby dane wyjściowe były openssl ciphersbardziej czytelne:

$ 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

Użycie tylko expand -t31zwiększyłoby szerokość wydruku z około 100 znaków do ponad 160 znaków.


1
Łatwiejszym sposobem jest użycie column:openssl ciphers -v 'HIGH' | column -t
muru

0

Wiele terminali obsługuje ustawianie zmiennych tabulatorów. Te, które są w wersji vt100, linux i lub obsługują standard EMCA-48, większość terminów na temat ustawień tabulatora obsługuje obsługę linuxa: xterm i rodzina (uxterm, urxvt) xfce4-terminal, luit, Terminal, SecureTTY, między innymi.

Napisałem więc skrypt kilka lat temu, aby ustawić moje zakładki przy logowaniu na każde 2 spacje - kiedyś użyłem 4, potem 3 przez krótki czas, a teraz o 2 ....

Więc teraz, jeśli „przechwycę” plik, zakładki w pliku rozwiną się do ustawień mojego terminala.

Jeśli przeszedłem przez vima lub więcej, robią oni własne tabulatory, ale wiele narzędzi używa tabulatorów.

Zawiera skrypt w celach informacyjnych i / lub do użytku osobistego:

#!/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

Mam nadzieję, że to pomoże...


-2

Według strony, kot nie może tego zrobić sam. Ale możesz np. Uruchomić dane wyjściowe z cat przez trfiltr, aby zastąpić tabulatory dowolną liczbą spacji:

cat somefile | tr '\t' '  '

zastąpi znak tabulacji dwoma spacjami.

Aktualizacja: jak wskazano w komentarzach do tego postu, tak naprawdę to nie działa. Niemniej jednak zachowuję odpowiedź jako przykład tego, jak tego nie robić.


3
W rzeczywistości zastępuje '\t'go tylko jedna spacja, bez względu na to, ile spacji znajduje się między drugą parą cudzysłowów' '
Meysam

3
trnie działa w ten sposób .. każdy bajt arg 1 jest zastępowany przez każdy odpowiadający bajt arg 2 ..... Dlatego printf '\t' |tr '\t' 'ळ' wypisuje pojedynczy bajt, którego wartość szesnastkowa to \xE0.., który jest pierwszym bajtem z trzech UTF-8 zakodowane bajty, które składają się na znak (którego wartość Unicode CodePoint to U + 0933)
Peter.O

Ach, oczywiście. Dzięki za złapanie mojego głupiego błędu!
Petr Uzel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.