Comment utiliser une colonne pour délimiter des tabulations et non des espaces?

59

J'aimerais utiliser la columncommande Unix pour formater du texte. J'ai des champs délimités par des onglets, mais dans chaque champ, il y a aussi des espaces. columndélimite les espaces blancs (onglets et espaces). Comment faire en sorte que les colonnes utilisent uniquement des tabulations comme délimiteur?

J'essayais de spécifier l'onglet comme délimiteur en utilisant:

cat myfile | column -t -s"\t"
tortue
la source

Réponses:

82
column -t -s '\t'

séparerait les colonnes \et les tcaractères.

column -s \test identique à column -s t, car la barre oblique inverse est interprétée par le shell comme un opérateur de cotation.

Ici, vous voulez passer un vrai caractère de tabulation à la colonne. Avec ksh93, zsh, bash, mksh, busybox sh ou FreeBSD sh:

column -ts $'\t'

Ou entrez un caractère de tabulation réel en tapant Ctrl-V Tabà l'invite du shell (entre guillemets ou précédé d'une barre oblique inversée car le caractère de tabulation est un séparateur de jeton dans la syntaxe du shell, tout comme l'espace), ou utilisez "$(printf '\t')"(ces guillemets nécessaires pour désactiver le split + glob opérateur car le caractère de tabulation se trouve également dans la valeur par défaut de $IFS).

Stéphane Chazelas
la source
3
Je devais faire ce column -t -s $'\t'que bash semblait penser à '\t'la fois \ et t, mais $'\t'signifie un onglet littéral. Bash pue
ThorSummoner
Si vous avez besoin de la conformité POSIX (aidez-moi), veuillez consulter ma réponse, qui est fortement basée sur cette réponse fantastique!
Nick Bull
Cette solution a fonctionné pour moi - le $'\t'fabricant marque le délimiteur. Mais je suis presque sûr awk -F "\t"d’utiliser un onglet comme délimiteur pour awk. Pourquoi cela fonctionne et pas ici pour la colonne?
Mike
3

J'ai utilisé ce qui suit (ne fonctionne que si votre texte ne contient pas |):

cat myfile | tr '\t' '|' | column -t -s '|'

Cela remplace simplement les onglets par des tuyaux, puis utilise colonne avec des tuyaux comme délimiteurs.

(Je l'ai fait parce que je n'ai rien vu dans la réponse de Stéphane qui fonctionne parfaitement dans la coquille du poisson. Sinon, la réponse de Stéphane semble bonne.)

Aaron Feldman
la source
3

Pour POSIX, $'...'connu sous le nom d'échappement ANSI-C, n'est pas défini.

Au lieu de cela, vous pouvez utiliser $(printf '\t'):

column -t -s "$(printf '\t')"

$(printf '\011')peut être utilisé, car 011(la représentation octale de la décimale 9) est le code ANSI pour un caractère de tabulation horizontale:

column -t -s "$(printf '\011')"

Cependant, voir ci-dessous le commentaire de Stéphane Chazelas pour expliquer pourquoi cela peut ne pas être cohérent d'une version à l'autre du shell.

Nick Bull
la source
2
Notez que POSIX ne spécifie pas le codage de la tabulation. Il existe encore des systèmes POSIX dont le codage des paramètres régionaux C est basé sur EBCDIC, où TAB est égal à 5 ​​et non 9 comme en ASCII. Dans la mesure du possible, il est préférable de faire référence aux caractères par leur nom pour éviter ce genre de problème, comme "$(printf '\t')"indiqué dans ma réponse. Notez que $'...'son inclusion dans la prochaine version majeure de la spécification POSIX est prévue.
Stéphane Chazelas
@ StéphaneChazelas est $(printf '\t')POSIX? Je vous remercie!
Nick Bull
3
oui
Stéphane Chazelas
@ StéphaneChazelas Merci beaucoup, j'ai mis à jour ma réponse pour y inclure votre conseil très utile :)
Nick Bull
2

Le -test pour sélectionner le nombre de colonnes que vous voulez. Laisser ce vide ne change rien. En outre, vous voulez un espace après le, -salors essayez ceci:

cat myfile | column -s \t

lurker
la source
Merci. C'est proche de ce que je cherche. Cependant, toutes les lignes sont maintenant fusionnées sur une seule ligne. Comment puis-je garder chaque ligne sur sa propre ligne?
tortue
Par défaut, columnremplit les lignes avant les colonnes. Vous pouvez être intéressé parpr
lurker