Par exemple. J'ai un fichier (produit avec echo -e "var1\tvar2\t\var3\tvar4" > foo
) qui sont affichés en tant que:
$ cat foo
case elems meshing nlsys
uniform 2350 0.076662 2.78
non-conformal 348 0.013332 0.55
scale 318 0.013333 0.44
smarter 504 0.016666 0.64
submodel 360 .009999 0.40
unstruct-quad 640 0.019999 0.80
unstruct-tri 1484 0.01 0.88
Je préfère la sortie comme ceci (ici j'ai utilisé vim
et :set tabstop=14
):
case elems meshing nlsys
uniform 2350 0.076662 2.78
non-conformal 348 0.013332 0.55
scale 318 0.013333 0.44
smarter 504 0.016666 0.64
submodel 360 .009999 0.40
unstruct-quad 640 0.019999 0.80
unstruct-tri 1484 0.01 0.88
Je peux obtenir les mêmes fonctionnalités avec cat
si j'utilise $ tabs=15
en bash (voir ceci question ). Existe-t-il un programme qui effectue ce type de formatage automatiquement? Je ne veux pas expérimenter avec la valeur tabs
avant cat
ing un fichier.
J'utilise habituellement le programme column
pour cela, il est dans un paquet appelé bsdmainutils
sur Debian:
column -t foo
Production:
case elems meshing nlsys
uniform 2350 0.076662 2.78
non-conformal 348 0.013332 0.55
scale 318 0.013333 0.44
smarter 504 0.016666 0.64
submodel 360 .009999 0.40
unstruct-quad 640 0.019999 0.80
unstruct-tri 1484 0.01 0.88
Extrait de column(1)
sur mon système:
...
-t Determine the number of columns the input contains and create a
table. Columns are delimited with whitespace, by default, or
with the characters supplied using the -s option. Useful for
pretty-printing displays.
...
Plusieurs options:
var1=uniform var2=2350 var3=0.076662 var4=2.78
printf '%-15s %-10s %-12s %s\n' \
case elems messing nlsys \
"$var1" "$var2" "$var3" "$var4"
printf '%s\t%s\t%s\t%s\n' \
case elems messing nlsys \
"$var1" "$var2" "$var3" "$var4" |
expand -t 15,25,37
printf '%s\t%s\t%s\t%s\n' \
case elems messing nlsys \
"$var1" "$var2" "$var3" "$var4" |
column -t -s $'\t'
la colonne est une commande non standard, certaines implémentations/versions ne prennent pas en charge l'option -s. Il calcule la largeur de la colonne en fonction de l'entrée, mais cela signifie qu'il ne peut commencer à s'afficher qu'une fois que toute l'entrée lui a été fournie. $'...'
est la syntaxe ksh93 également trouvée dans zsh et bash.
Avec zsh:
values=(
case elems messing nlsys
"$var1" "$var2" "$var3" "$var4"
)
print -arC4 -- "$values[@]"
Vous pouvez également utiliser rs
comme alternative à column -t
:
(x=$(cat);rs -c -z $(wc -l<<<"$x")<<<"$x")
-c
modifie le séparateur de colonne d'entrée, mais -c
seul définit le séparateur de colonnes d'entrée sur un onglet. -z
définit la largeur de chaque colonne sur la largeur de l'entrée la plus longue de la colonne au lieu de rendre toutes les colonnes de la même largeur. Si certaines lignes ont moins de colonnes que la première ligne, ajoutez -n
.
Un autre outil qui peut le faire est tsv-pretty
de tilitaires TSV d'eBay (avertissement: je suis l'auteur). Il faut l'étape supplémentaire de l'alignement des champs numériques sur le point décimal. Par exemple:
$ tsv-pretty foo
case elems meshing nlsys
uniform 2350 0.076662 2.78
non-conformal 348 0.013332 0.55
scale 318 0.013333 0.44
smarter 504 0.016666 0.64
submodel 360 .009999 0.40
unstruct-quad 640 0.019999 0.80
unstruct-tri 1484 0.01 0.88
Il existe plusieurs options de formatage. Par exemple, -u
souligne l'en-tête et -f
formate les flottants dans un champ de manière similaire pour la lisibilité:
$ tsv-pretty foo -f -u
case elems meshing nlsys
---- ----- ------- -----
uniform 2350 0.076662 2.78
non-conformal 348 0.013332 0.55
scale 318 0.013333 0.44
smarter 504 0.016666 0.64
submodel 360 0.009999 0.40
unstruct-quad 640 0.019999 0.80
unstruct-tri 1484 0.010000 0.88
Plus d'informations sont disponibles dans la référence tsv-pretty .
function printTable()
{
local -r delimiter="${1}"
local -r data="$(removeEmptyLines "${2}")"
if [[ "${delimiter}" != '' && "$(isEmptyString "${data}")" = 'false' ]]
then
local -r numberOfLines="$(wc -l <<< "${data}")"
if [[ "${numberOfLines}" -gt '0' ]]
then
local table=''
local i=1
for ((i = 1; i <= "${numberOfLines}"; i = i + 1))
do
local line=''
line="$(sed "${i}q;d" <<< "${data}")"
local numberOfColumns='0'
numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")"
# Add Line Delimiter
if [[ "${i}" -eq '1' ]]
then
table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
fi
# Add Header Or Body
table="${table}\n"
local j=1
for ((j = 1; j <= "${numberOfColumns}"; j = j + 1))
do
table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")"
done
table="${table}#|\n"
# Add Line Delimiter
if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]]
then
table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
fi
done
if [[ "$(isEmptyString "${table}")" = 'false' ]]
then
echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1'
fi
fi
fi
}
function removeEmptyLines()
{
local -r content="${1}"
echo -e "${content}" | sed '/^\s*$/d'
}
function repeatString()
{
local -r string="${1}"
local -r numberToRepeat="${2}"
if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
then
local -r result="$(printf "%${numberToRepeat}s")"
echo -e "${result// /${string}}"
fi
}
function isEmptyString()
{
local -r string="${1}"
if [[ "$(trimString "${string}")" = '' ]]
then
echo 'true' && return 0
fi
echo 'false' && return 1
}
function trimString()
{
local -r string="${1}"
sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,'
}
EXEMPLES D'EXÉCUTION
$ cat data-1.txt
HEADER 1,HEADER 2,HEADER 3
$ printTable ',' "$(cat data-1.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
$ cat data-2.txt
HEADER 1,HEADER 2,HEADER 3
data 1,data 2,data 3
$ printTable ',' "$(cat data-2.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
| data 1 | data 2 | data 3 |
+-----------+-----------+-----------+
$ cat data-3.txt
HEADER 1,HEADER 2,HEADER 3
data 1,data 2,data 3
data 4,data 5,data 6
$ printTable ',' "$(cat data-3.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
| data 1 | data 2 | data 3 |
| data 4 | data 5 | data 6 |
+-----------+-----------+-----------+
$ cat data-4.txt
HEADER
data
$ printTable ',' "$(cat data-4.txt)"
+---------+
| HEADER |
+---------+
| data |
+---------+
$ cat data-5.txt
HEADER
data 1
data 2
$ printTable ',' "$(cat data-5.txt)"
+---------+
| HEADER |
+---------+
| data 1 |
| data 2 |
+---------+
REF LIB sur: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
La question concernait la sortie de colonnes délimitées par des tabulations.
La bonne réponse est donc une petite adaptation de la réponse de @nisetama. J'ai ajouté l'option -C $ '\ t' qui définit le formatage de sortie.
x=$(cat foo2); rs -C$'\t' $(wc -l <<<"$x") <<<"$x"
Bravo à @nisetama cependant :)