Ändern Sie die Tab-Größe des Befehls "cat"

15

Wenn ich in vimbin, kann ich die Größe der Registerkarte mit dem folgenden Befehl ändern:

:set ts=4

Ist es möglich, die Tabulatorgröße auch für die catBefehlsausgabe festzulegen?

Meysam
quelle

Antworten:

21

Der erste Befehl hier emuliert die Formatierung, die Sie in sehen vim. Es erweitert die Tabulatoren auf intelligente Weise auf die entsprechende Anzahl von Leerzeichen, basierend auf einer Tabstopp-Einstellung (ts) für jeweils 4 Spalten.

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

Ausgabe

ab  cd  de

Um die Tabulatoren als Tabulatoren beizubehalten und die Tabulator- STOP- Positionen auf jede vierte Spalte zu setzen, müssen Sie die Art und Weise ändern, in der die Umgebung mit Tabulatoren arbeitet (genau wie bei vim mit dem :set ts=4Befehl).

Beispielsweise können Sie im Terminal mit diesem Befehl die Registerkarte STOP auf 4 setzen.

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

Ausgabe

ab  cd  de
Peter.O
quelle
gut zu wissen (1). Befehl expand(from coreutils package) und tabs(from ncurses package), (2). und die Bedeutung von ts ist [ T ] ab [ S ] top
LiuYan 刘 刘
10

Verwenden Sie einfach den folgenden Code:

tabs -n

Wobei n die Anzahl der Leerzeichen ist, denen auch Tabulatoren entsprechen sollen. Um dies nicht jedes Mal tun zu müssen, wenn Sie die Shell starten, bearbeiten Sie einfach Ihr .bash_profilein ~/und fügen Sie die obige Zeile am Ende der Datei hinzu.

Weitere Informationen zum Befehl tabs finden Sie unter:

man tabs
Gustavo Bezerra
quelle
2
Beachten Sie jedoch, dass eine dauerhafte Änderung der Breite Ihrer Standard-Tabs andere Befehle lsdurcheinander bringen kann (z. B. dass die Ausgabe möglicherweise nicht richtig ausgerichtet ist).
Gustavo Bezerra
9

Es gibt keine Vorstellung von Tabulatoren oder Tabulatorenstopps cat; Das Programm fügt nur die Eingaben in die Ausgabe ein und behandelt Registerkarten wie jedes andere Zeichen. Handelt es sich bei dem Ausgabegerät um ein Terminal, werden die Registerkarten entsprechend dem Verhalten behandelt, für das das Terminal konfiguriert ist.

Systeme, die POSIX.1 implementieren, verfügen über einen Befehl tabs(1), mit dem das Konzept des Terminals für die Anzeige von Registerkarten angepasst wird. Abhängig von einem bestimmten Registerkartenlayout ist dies keine gute Idee, da Ihre Datei möglicherweise an ein anderes Gerät gesendet wird, z. B. an einen Drucker, der nicht das tut, was Sie beabsichtigt haben.

Wenn Sie tsin vim(oder normal vi) anpassen , müssen Sie nur anpassen, wie der Editor Tabulatorzeichen interpretiert, wenn sie angezeigt werden. Es hat keinen Einfluss darauf, was in der Datei endet.

Blrfl
quelle
Danke für die Erklärung. Wie ist der Drucker für die Behandlung von Registerkarten konfiguriert?
Meysam
Die meisten Drucker behandeln sie wie die meisten Terminals standardmäßig: den linken Rand und alle acht Zeichen danach.
Blrfl
5

Basierend auf den obigen Antworten und Beispielen scheint es, dass der tatsächliche Befehl, den das OP wollte, ...

cat somefile | expand -t4

Dies funktioniert für mich unter Red Hat 6.4.

ScotlynHatt
quelle
2

Um die bereits gegebenen Antworten zu erweitern, expandkann auch eine Liste von Tabulatorpositionen eingenommen werden. Dies ist nützlich, wenn die Inhaltslängen der verschiedenen Spalten sehr unterschiedlich sind.

Ich bin heute auf diese Anforderung gestoßen, als ich die Ausgabe von openssl cipherslesbarer machen wollte :

$ 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

Wenn Sie nur verwenden expand -t31, wird die Breite der Ausgabe von ca. 100 Zeichen auf über 160 Zeichen erhöht.

Alexander Stumpf
quelle
1
Ein einfacherer Weg dies zu tun ist column:openssl ciphers -v 'HIGH' | column -t
muru
0

Viele Terminals unterstützen das Einstellen variabler Tabstopps. Diejenigen, die vt100, Linux und / oder den EMCA-48-Standard unterstützen, tun dies, die meisten Begriffe in Bezug auf die Größe der Registerkarte für die Linux-Unterstützung: xterm und family (uxterm, urxvt) xfce4-terminal, luit, Terminal, SecureTTY, unter anderem.

Also schrieb ich vor ein paar Jahren ein Skript, um meine Tabs bei der Anmeldung auf 2 Leerzeichen zu setzen.

Wenn ich jetzt eine Datei 'cat', werden die Registerkarten in der Datei auf die Einstellungen meines Terminals erweitert.

Wenn ich durch vim oder mehr gekommen bin, haben sie ihre eigene Tab-Erweiterung, aber viele Utils verwenden Tabs.

Enthält das Skript hier als Referenz und für den persönlichen Gebrauch:

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

Ich hoffe es hilft...

Astara
quelle
-2

Laut der Manpage kann cat das nicht alleine machen. Sie können jedoch z. B. die Ausgabe von cat durch trfilter ausführen , um die Tabulatoren durch eine beliebige Anzahl von Leerzeichen zu ersetzen:

cat somefile | tr '\t' '  '

wird das Tabulatorzeichen durch zwei Leerzeichen ersetzen.

Update: Wie in den Kommentaren zu diesem Beitrag erwähnt, funktioniert dies tatsächlich nicht . Trotzdem behalte ich die Antwort als Beispiel dafür, wie man es nicht macht.

Petr Uzel
quelle
3
Es wird tatsächlich durch '\t'nur ein Leerzeichen ersetzt, egal wie viele Leerzeichen zwischen dem zweiten Paar von Anführungszeichen stehen' '
Meysam
3
trfunktioniert so nicht .. jedes Byte von arg 1 wird durch jedes entsprechende Byte von arg 2 ersetzt ..... Gibt daher printf '\t' |tr '\t' 'ळ' ein einzelnes Byte aus, dessen hexadezimaler Wert \xE0.. ist und das das erste Byte der drei UTF-8 ist codierte Bytes, aus denen das Zeichen besteht (deren Unicode-CodePoint-Wert U + 0933 ist)
Peter.O
Ah, natürlich. Danke, dass du meinen dummen Fehler aufgefangen hast!
Petr Uzel