Couper peut prendre plusieurs plages en -f
:
Colonnes jusqu'à 4 et à partir de 7 :
cut -f -4,7-
ou pour les champs 1,2,5,6 et à partir de 10 :
cut -f 1,2,5,6,10-
etc
La première partie de votre question est simple. Comme déjà souligné, cut accepte l'omission de l'index de début ou de fin d'une plage de colonnes, l'interprétant comme signifiant soit "du début à la colonne n (inclus)" ou "de la colonne n (inclus) à la fin », respectivement :
$ printf 'this:is:a:test' | cut -d: -f-2
this:is
$ printf 'this:is:a:test' | cut -d: -f3-
a:test
Il prend également en charge la combinaison gammes. Si vous voulez, par exemple, les 3 premières et les 2 dernières colonnes dans une rangée de 7 colonnes :
$ printf 'foo:bar:baz:qux:quz:quux:quuz' | cut -d: -f-3,6-
foo:bar:baz:quux:quuz
Cependant, la deuxième partie de votre question peut être un peu plus délicate en fonction du type d'entrée que vous attendez. Si par "dernier n colonnes" vous voulez dire "dernier n colonnes (indépendamment de leurs indices dans la ligne globale)" (c'est-à-dire parce que vous ne savez pas nécessairement combien de colonnes vous allez trouver à l'avance) alors malheureusement ce n'est pas possible d'accomplir en utilisant cut
seul. Afin d'utiliser efficacement cut
pour sortir "le dernier n colonnes" dans chaque ligne, le nombre total des colonnes présentes dans chaque ligne doivent être connues au préalable, et chaque ligne doit être cohérente dans le nombre de colonnes qu'elle contient.
Si vous ne le faites pas savoir combien de "colonnes" peuvent être présentes dans chaque ligne (par exemple parce que vous travaillez avec une entrée qui n'est pas strictement tabulaire), alors vous devrez utiliser quelque chose comme awk
Au lieu. Par exemple, pour utiliser awk
pour extraire les 2 dernières "colonnes" (awk les appelle champs, dont le nombre peut varier par ligne) de chaque ligne de saisie :
$ printf '/a\n/a/b\n/a/b/c\n/a/b/c/d\n' | awk -F/ '{print $(NF-1) FS $(NF)}'
/a
a/b
b/c
c/d
Pour utiliser AWK pour couper les premier et dernier champs :
awk '{$1 = ""; $NF = ""; print}' inputfile
Malheureusement, cela laisse les séparateurs de champs, donc
aaa bbb ccc
devient
[space]bbb[space]
Pour ce faire, utilisez la réponse de kurumi qui ne laissera pas d'espaces supplémentaires, mais d'une manière spécifique à vos besoins :
awk '{delim = ""; for (i=2;i<=NF-1;i++) {printf delim "%s", $i; delim = OFS}; printf "\n"}' inputfile
Cela corrige également quelques problèmes dans cette réponse.
Pour généraliser cela :
awk -v skipstart=1 -v skipend=1 '{delim = ""; for (i=skipstart+1;i<=NF-skipend;i++) {printf delim "%s", $i; delim = OFS}; printf "\n"}' inputfile
Ensuite, vous pouvez modifier le nombre de champs à ignorer au début ou à la fin en modifiant les affectations de variables au début de la commande.
Vous pouvez couper en utilisant ce qui suit,
-d :délimiteur ,-f pour les champs
\t utilisé pour les champs séparés par des tabulations
cut -d$'\t' -f 1-3,7-