When I am in vim I can change the tab size with the following command:
:set ts=4
Is it possible to set tab size for cat command output too?
When I am in vim I can change the tab size with the following command:
:set ts=4
Is it possible to set tab size for cat command output too?
The first command here emulates the formatting you see in vim. It intelligently expands tabs to the equivalent number of spaces, based on a tab-STOP (ts) setting of every 4 columns.
printf "ab\tcd\tde\n" |expand -t4
Output
ab cd de
To keep the tabs as tabs and have the tab STOP positions set to every 4th column, then you must change the way the environment works with a tab-char (just as vim does with the :set ts=4 command)
For example, in the terminal, you can set the tab STOP to 4 with this command;
tabs 4; printf "ab\tcd\tde\n"
Output
ab cd de
Just use the following code:
tabs -n
Where n is the number of spaces you want tabs to correspond too.
In order to not having to do this every time you start the shell, just edit your .bash_profile in ~/ and add the above line to the end of the file.
For further info about the tabs command, refer to:
man tabs
There's no notion of tabs or tab stops in cat; the program just funnels the inputs to the output and treats tabs like any other character. If the output device happens to be a terminal, tabs will be handled according to whatever behavior the terminal is configured to provide.
Systems implementing POSIX.1 have a command called tabs(1) that will adjust the terminal's concept of how tabs should be displayed. Depending on a particular tab layout is not considered a good idea, as someone may send your file to some other device such as a printer that won't do what you intended.
When you adjust ts in vim (or plain vi), all you're doing is adjusting how the editor interprets tab characters when displayed. It has no bearing on what ends up in the file.
Based on the above answers and examples, it would seem that the actual command the OP wanted is...
cat somefile | expand -t4
This works for me on Red Hat 6.4.
To expand on the already given answers, expand can also take a list of tab stop positions. This is useful if the content lengths of the varlious columns varies a lot.
I came over this requirement today when I wanted to make the output of openssl ciphers more readable:
$ 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
Using only expand -t31 would blow up the width of the output from around 100 characters to more than 160 characters.
For X terminal emulators (eg. $TERM is xterm, st, etc.):
$ tabs -N
For virtual consoles (no X Server, only text console where $TERM is linux, etc.):
$ setterm --tegtabs N
Where N is an integer number of spaces to be used for TAB.
Sed way insead of tr which translates SET1 to SET2 of characters in 1:1 'proportions':
$ sed 's/\t/ /g' FILENAME
^^^^^
spaces here
Many terminals support setting variable tab stops. Those that are vt100, linux and or support the EMCA-48 standard do, most terms on linux support setting tab size: xterm and family (uxterm, urxvt) xfce4-terminal, luit, Terminal, SecureTTY, among others.
So wrote a script a few years back to set my tabs at login to every 2 spaces -- used to use 4, then 3 for a short bit, and now at 2....
So now, if I 'cat' a file, tabs in the file will expand to my terminal's setting.
If I got through vim or more, they do their own tab expansion, but alot of utils use tabs.
Will include the script here for reference, and or personal use:
#!/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
Hope it helps...
According to the manpage, cat can not do it on its own. But you can e.g. run the output from cat through tr filter to replace the tabs with any number of spaces you wish:
cat somefile | tr '\t' ' '
will replace the tab character with two spaces.
Update: as pointed out in the comments to this post, this actually does not work. Nevertheless, I'm keeping the answer as an example of how not to do it.