เปลี่ยนขนาดแท็บของคำสั่ง“ cat”


15

เมื่อฉันอยู่vimฉันสามารถเปลี่ยนขนาดแท็บด้วยคำสั่งต่อไปนี้:

:set ts=4

เป็นไปได้ไหมที่จะกำหนดขนาดแท็บสำหรับcatเอาต์พุตคำสั่งด้วย?

คำตอบ:


21

คำสั่งแรกที่นี่จำลองvimการจัดรูปแบบที่คุณเห็นใน มันขยายแท็บอย่างชาญฉลาดไปยังจำนวนช่องว่างที่เทียบเท่าโดยขึ้นอยู่กับการตั้งค่า tab-STOP (ts) ของทุก 4 คอลัมน์

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

เอาท์พุต

ab  cd  de

เพื่อให้แท็บเป็นแท็บและตั้งตำแหน่งแท็บSTOPให้ทุกคอลัมน์ที่ 4 คุณต้องเปลี่ยนวิธีที่สภาพแวดล้อมทำงานกับ tab-char (เช่นเดียวกับที่ vim ใช้กับ:set ts=4คำสั่ง)

ตัวอย่างเช่นในเทอร์มินัลคุณสามารถตั้งค่าแท็บSTOPเป็น 4 ด้วยคำสั่งนี้

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

เอาท์พุต

ab  cd  de

ดีใจที่ได้ทราบ (1) expandคำสั่ง (จากแพ็คเกจ coreutils) และtabs(จากแพ็คเกจ ncurses), (2) และความหมายของ ts คือ [ T ] ab [ S ] ด้านบน
LiuYan 刘研

10

เพียงใช้รหัสต่อไปนี้:

tabs -n

โดยที่ n คือจำนวนช่องว่างที่คุณต้องการให้แท็บสอดคล้องกันด้วย เพื่อที่จะไม่ต้องทำเช่นนี้ทุกครั้งที่คุณเริ่มเปลือกเพียงการแก้ไขของคุณ.bash_profileใน~/และเพิ่มบรรทัดข้างต้นไปยังจุดสิ้นสุดของแฟ้ม

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับคำสั่ง tabs อ้างถึง:

man tabs

2
เพียงแค่ระวังว่าการเปลี่ยนความกว้างแท็บเริ่มต้นของคุณอย่างถาวรอาจทำให้คำสั่งอื่นผิดพลาด (ตัวอย่างเช่นlsการย้ายออกอาจดูไม่สอดคล้องกัน)
Gustavo Bezerra

9

มีความคิดของแท็บหรือแท็บหยุดในไม่มีcat; โปรแกรมเพียงช่องทางอินพุตกับเอาต์พุตและใช้แท็บเหมือนอักขระอื่น ๆ หากอุปกรณ์เอาท์พุทเป็นเทอร์มินัลแท็บจะได้รับการจัดการตามลักษณะการทำงานที่เทอร์มินัลกำหนดค่าไว้

ระบบที่ใช้ POSIX.1 จะมีคำสั่งtabs(1)ที่จะปรับแนวคิดของเทอร์มินัลว่าจะแสดงแท็บอย่างไร ขึ้นอยู่กับเค้าโครงของแท็บเฉพาะนั้นไม่ถือเป็นความคิดที่ดีเพราะบางคนอาจส่งไฟล์ของคุณไปยังอุปกรณ์อื่น ๆ เช่นเครื่องพิมพ์ที่จะไม่ทำสิ่งที่คุณต้องการ

เมื่อคุณปรับtsในvim(หรือธรรมดาvi) สิ่งที่คุณทำคือการปรับวิธีที่ตัวแก้ไขตีความอักขระแท็บเมื่อแสดง มันไม่มีผลต่อสิ่งที่เกิดขึ้นในไฟล์


ขอบคุณสำหรับคำอธิบาย เครื่องพิมพ์ได้รับการกำหนดค่าให้ปฏิบัติแท็บอย่างไร
Meysam

เครื่องพิมพ์ส่วนใหญ่ปฏิบัติต่อพวกเขาในลักษณะเดียวกับที่เทอร์มินัลส่วนใหญ่ทำตามค่าเริ่มต้น: ระยะขอบด้านซ้ายและทุก ๆ แปดอักขระหลังจากนั้น
Blrfl

5

จากคำตอบและตัวอย่างข้างต้นดูเหมือนว่าคำสั่ง OP ที่ต้องการคือ ...

cat somefile | expand -t4

สิ่งนี้ใช้ได้กับฉันใน Red Hat 6.4


2

หากต้องการขยายคำตอบที่ได้รับแล้วexpandยังสามารถรับรายการตำแหน่งแท็บหยุดได้ด้วย สิ่งนี้มีประโยชน์หากความยาวเนื้อหาของคอลัมน์ varlious แตกต่างกันมาก

ฉันมาข้อกำหนดนี้วันนี้เมื่อฉันต้องการให้ผลลัพธ์ที่openssl ciphersอ่านง่ายขึ้น:

$ 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

การใช้expand -t31จะทำให้ความกว้างของเอาต์พุตจากประมาณ 100 ตัวอักษรเป็นมากกว่า 160 ตัวอักษรเท่านั้น


1
วิธีที่ง่ายกว่าคือการใช้column:openssl ciphers -v 'HIGH' | column -t
muru

0

เทอร์มินัลจำนวนมากรองรับการตั้งค่าแท็บตัวแปรหยุด สิ่งเหล่านั้นคือ vt100, linux และหรือสนับสนุนมาตรฐาน EMCA-48 ทำข้อกำหนดส่วนใหญ่เกี่ยวกับขนาดแท็บการตั้งค่าการสนับสนุน linux: xterm และตระกูล (uxterm, urxvt) xfce4-terminal, luit, Terminal, SecureTTY และอื่น ๆ

ดังนั้นเขียนสคริปต์ไม่กี่ปีหลังตั้งแท็บของฉันที่เข้าสู่ระบบทุก 2 ช่องว่าง - เคยใช้ 4 จากนั้น 3 สำหรับสั้น ๆ และตอนนี้ที่ 2 ....

ดังนั้นตอนนี้ถ้าฉัน 'cat' ไฟล์แท็บในไฟล์จะขยายไปสู่การตั้งค่าเทอร์มินัลของฉัน

ถ้าฉันผ่านเป็นกลุ่มหรือมากกว่าพวกเขาจะขยายแท็บของตัวเอง แต่มีประโยชน์มากมายที่ใช้แท็บ

จะรวมสคริปต์ที่นี่เพื่อการอ้างอิงและหรือการใช้งานส่วนตัว:

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

หวังว่ามันจะช่วย ...


-2

ตาม manpage แมวไม่สามารถทำได้ด้วยตัวเอง แต่คุณสามารถเรียกใช้เอาต์พุตจาก cat ผ่านtrตัวกรองเพื่อแทนที่แท็บด้วยจำนวนช่องว่างที่คุณต้องการ:

cat somefile | tr '\t' '  '

จะแทนที่อักขระแท็บด้วยช่องว่างสองช่อง

อัปเดต: ตามที่ระบุไว้ในความคิดเห็นในโพสต์นี้สิ่งนี้ไม่ได้ผล อย่างไรก็ตามผมรักษาคำตอบที่เป็นตัวอย่างของวิธีการที่ไม่ได้ที่จะทำมัน


3
จริง ๆ แล้วมันจะแทนที่'\t'ด้วยช่องว่างเดียวเท่านั้นไม่ว่าจะมีช่องว่างจำนวนเท่าใดระหว่างเครื่องหมายคำพูดคู่ที่สอง' '
Meysam

3
trไม่ทำงานอย่างนั้น .. แต่ละไบต์ของหาเรื่อง 1 จะถูกแทนที่โดยแต่ละไบต์ที่สอดคล้องกันของหาเรื่อง 2 ..... จึงprintf '\t' |tr '\t' 'ळ' พิมพ์ไบต์เดียวที่มีค่าฐานสิบหก\xE0.. ซึ่งเป็นไบต์แรกของสาม UTF-8 ไบต์ที่เข้ารหัสซึ่งประกอบขึ้นเป็นอักขระ(ซึ่งค่า Unicode CodePoint คือ U + 0933)
Peter.O

อ่าแน่นอน ขอบคุณที่ติดตามความผิดพลาดของฉัน!
Petr Uzel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.