web-dev-qa-db-fra.com

Utilisation de la commande cut pour supprimer plusieurs colonnes

entrée donnée

 echo 1,2,3,4,5,6,7,8,9, ... 100 

Si je veux couper les colonnes 5 je peux faire

 cut -d, -f-4,6 -

que faire si je veux couper plusieurs colonnes non consécutives, telles que 5, 7, etc., y a-t-il une seule ligne?

51
user121196

Vous devriez pouvoir continuer les séquences directement dans votre spécification -f existante.

Pour sauter 5 et 7, essayez:

cut -d, -f-4,6-6,8-

Lorsque vous ignorez une seule colonne séquentielle, vous pouvez également écrire ceci:

cut -d, -f-4,6,8-

Pour continuer, si vous vouliez sauter 5, 7 et 11, vous utiliseriez:

cut -d, -f-4,6-6,8-10,12-

Pour le mettre en perspective plus clairement, il est plus facile de visualiser lorsque vous utilisez les colonnes de début/fin qui vont au début/à la fin de la liste de séquences, respectivement. Par exemple, ce qui suit imprimera les colonnes 2 à 20, en ignorant les colonnes 5 et 11:

cut -d, -f2-4,6-10,12-20

Donc, cela va imprimer "2 à 4", sauter 5, "6 à 10", sauter 11, puis "12 à 20".

74
newfurniturey

Parfois, il est plus facile de penser en termes de champs à exclure.

Si le nombre de champs non coupés (non conservés dans la sortie) est faible, il peut être plus facile d’utiliser le drapeau --complement, par exemple. pour inclure tous les champs 1-20 sauf les champs 3, 7 et 12, procédez comme suit:

cut -d, --complement -f3,7,12 <inputfile

Plutôt que

cut -d, -f-2,4-6,8-11,13-
13
Chris Johnson

Vous pouvez couper toutes les colonnes paires/impaires en utilisant seq:

Cela imprimerait toutes les colonnes impaires

echo 1,2,3,4,5,6,7,8,9,10 | cut -d, -f$(seq -s, 1 2 10)

Pour imprimer toutes les colonnes, vous pouvez utiliser

echo 1,2,3,4,5,6,7,8,9,10 | cut -d, -f$(seq -s, 2 2 10)

En modifiant le deuxième numéro de séquence, vous pouvez spécifier les colonnes à imprimer.

Si la spécification des colonnes à imprimer est plus complexe, vous pouvez également utiliser une "clause one-liner-if-" comme

echo 1,2,3,4,5,6,7,8,9,10 | cut -d, -f$(for i in $(seq 1 10); do if [[ $i -lt 10 && $i -lt 5 ]];then echo -n $i,; else echo -n $i;fi;done)

Cela imprimerait toutes les colonnes de 1 à 5. Vous pouvez simplement modifier les conditions pour créer des conditions plus complexes afin de spécifier le temps qu'une colonne doit être imprimée.

12
sge

La même chose pourrait être faite avec Perl
Comme il utilise une indexation basée sur 0 au lieu d'une indexation basée sur 1, les valeurs de champ sont décalées de 1

Perl -F, -lane 'print join ",", @F[1..3,5..9,11..19]'    

est équivalent à:

cut -d, -f2-4,6-10,12-20

Si les virgules ne sont pas nécessaires dans la sortie:

Perl -F, -lane 'print "@F[1..3,5..9,11..19]"'
0
Chris Koknat