J'ai le fichier suivant:
id name age
1 ed 50
2 joe 70
Je veux imprimer uniquement les colonnes id
et age
. En ce moment je viens d'utiliser awk
:
cat file.tsv | awk '{ print $1, $3 }'
Cependant, cela nécessite de connaître les numéros de colonne. Y a-t-il un moyen de le faire où je peux utiliser le nom de la colonne (spécifié sur la première ligne) au lieu du numéro de la colonne?
cat
n'est pas nécessaire, BTW. Vous pouvez utiliserawk '{ print $1, $3 }' file.tsv
id
au lieu$1
etage
au lieu de$3
Réponses:
Peut-être quelque chose comme ça:
Si vous souhaitez spécifier les colonnes à imprimer sur la ligne de commande, vous pouvez procéder comme suit:
(Notez le
-v
commutateur pour obtenir la variable définie dans leBEGIN
bloc.)la source
awk -f t.awk col1 col2 ... coln input
serait idéal;awk -f t.awk cols=col1,col2,...,coln input
fonctionnerait aussifor (i in out)
n'a pas d'ordre inhérent.gawk
offrePROCINFO["sorted_in"]
comme une solution, itérer sur l'indice avec unfor( ; ; )
est sans doute mieux.Introduire simplement une solution Perl dans le lot:
la source
csvkit
Convertir les données d'entrée à un format csv et utiliser un outil de csv tels que
csvcut
ducsvkit
:Installez csvkit:
Utiliser
tr
avec son option squeeze-s
pour le convertir en un fichier csv valide et appliquercsvcut
:Si vous souhaitez revenir à l'ancien format de données, vous pouvez utiliser
tr ',' ' ' | column -t
Remarques
csvkit prend également en charge différents délimiteurs ( option partagée
-d
ou--delimiter
), mais renvoie un fichier csv:Si le fichier utilise uniquement des espaces pour séparer les colonnes (aucun onglet), les travaux suivants
Si le fichier utilise un onglet pour séparer les colonnes, les opérations suivantes
csvformat
peuvent être utilisées pour récupérer le fichier tsv:Pour autant que j'ai vérifié, un seul onglet est autorisé.
csvlook
peut formater la table dans un format de table de démarquesUUOC (utilisation inutile de chat) : J'aime cette façon de construire la commande.
la source
tr
, aussi. Les fichiers TSV sont pris en charge directement, sans qu'il soit nécessaire de les convertir au format CSV. L' option-t
(aka--tabs
) indiquecvscut
d'utiliser des tabulations comme délimiteur de champ. Et-d
ou--delimiter
d'utiliser n'importe quel caractère comme délimiteur.-d
et-t
sont semi-cassées. ils travaillent pour spécifier le délimiteur d'entrée, mais le délimiteur de sortie est codé en dur pour toujours être une virgule. OMI qui est cassé - il devrait être identique au délimiteur d’entrée ou disposer d’une autre option permettant à l’utilisateur de définir le délimiteur de sortie, commeawk
les vars FS et OFS.Si vous souhaitez simplement faire référence à ces champs par leur nom plutôt que par leur numéro, vous pouvez utiliserread
:MODIFIER
J'ai enfin compris votre signification! Voici une fonction bash qui imprimera uniquement les colonnes que vous spécifiez sur la ligne de commande (par nom ).
Voici comment vous pouvez l'utiliser avec le fichier que vous avez présenté:
(La fonction lit
stdin
.< file.tsv printColumns ...
Est équivalentprintColumns ... < file.tsv
etcat file.tsv | printColumns ...
)Remarque: Faites attention aux noms des colonnes que vous demandez! Cette version manque de contrôle de cohérence, donc des choses désagréables peuvent arriver si l’un des arguments est quelque chose comme:
"anything; rm /my/precious/file"
la source
id
,name
etage
cela ne change rien au fait que la commande est codée en dur dans votreread
ligne.time { command(s); }
).time cat temp.txt | ./col1 CHR POS > /dev/null 99.144u 38.966s 2:19.27 99.1% 0+0k 0+0io 0pf+0w time awk -f col2 c1=CHR c2=POS temp.txt > /dev/null 0.294u 0.127s 0:00.50 82.0% 0+0k 0+0io 0pf+0w
Pour ce que ça vaut. Cela peut gérer un nombre quelconque de colonnes dans la source et un nombre illimité de colonnes à imprimer, dans la séquence de sortie de votre choix. il suffit de réorganiser les arguments ...
par exemple. appel:
script-name id age
sortie
la source
Si le fichier que vous lisez ne pourrait jamais être généré par l'utilisateur, vous pouvez abuser de la lecture intégrée:
La première ligne entière du fichier d'entrée est remplacée par la liste d'arguments.
read
Tous les noms de champs de la ligne d'en-tête sont donc transmis en tant que noms de variables. Le premier de ceux-ci se voit attribuer le 1 quiseq 100
génère, le second le 2, le troisième le 3 et ainsi de suite. L'excédent deseq
production est absorbé par la variable muetteextra
. Si vous connaissez le nombre de colonnes d'entrée à l'avance, vous pouvez modifier les 100 pour qu'elles correspondent et vous en débarrasserextra
.Le
awk
script est une chaîne entre guillemets, permettant deread
substituer dans le script les variables shell définies par en tant queawk
numéros de champs.la source
En général, il est plus facile de regarder l'en-tête du fichier, de compter le numéro de la colonne dont vous avez besoin ( c ), puis d'utiliser Unix
cut
:Mais quand il y a beaucoup de colonnes ou beaucoup de fichiers, j'utilise l'astuce laide suivante:
Testé sur OSX, il
file.csv
est délimité par des virgules.la source
Voici un moyen rapide pour sélectionner une seule colonne.
Disons que nous voulons la colonne nommée "foo":
Fondamentalement, prenez la ligne d'en-tête, divisez-la en plusieurs lignes avec un nom de colonne par ligne, numérotez les lignes, sélectionnez la ligne avec le nom souhaité et récupérez le numéro de ligne associé; utilisez ensuite ce numéro de ligne comme numéro de colonne de la commande de coupe.
la source
À la recherche d'une solution similaire (j'ai besoin de la colonne nommée id, qui peut avoir un numéro de colonne différent), je suis tombé sur celle-ci:
la source
J'ai écrit un script Python à cet effet qui fonctionne comme suit:
Je l'ai appelé
hgrep
pour l'en- tête grep , il peut être utilisé comme ceci:Le script entier est un peu plus long, car il utilise
argparse
pour analyser les arguments en ligne de commande et le code est le suivant:la source
awk
, pour tous ses millésimes, est par nature indexé intégralement, tel quelcut
.Voici plusieurs outils conçus pour gérer les données indexées par nom (la plupart d’entre eux ne traitent que les formats CSV et TSV, qui sont des formats de fichiers très populaires):
la source
Essayez ce petit utilitaire awk pour couper des en-têtes spécifiques - https://github.com/rohitprajapati/toyeca-cutter
Exemple d'utilisation -
la source