96

given input

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

If I want to cut columns 5 I can do

cut -d, -f-4,6-

what if I want to cut multiple non consecutive columns like 5, 7,etc is there a one liner?

jww
  • 97,681
  • 90
  • 411
  • 885
user121196
  • 30,032
  • 57
  • 148
  • 198

4 Answers4

145

You should be able to continue the sequences directly in your existing -f specification.

To skip both 5 and 7, try:

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

As you're skipping a single sequential column, this can also be written as:

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

To keep it going, if you wanted to skip 5, 7, and 11, you would use:

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

To put it into a more-clear perspective, it is easier to visualize when you use starting/ending columns which go on the beginning/end of the sequence list, respectively. For instance, the following will print columns 2 through 20, skipping columns 5 and 11:

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

So, this will print "2 through 4", skip 5, "6 through 10", skip 11, and then "12 through 20".

Nate
  • 1,442
  • 14
  • 22
newfurniturey
  • 37,556
  • 9
  • 94
  • 102
  • 2
    `6-6` probably works, but is more conventionally written as `6`. – Jonathan Leffler Dec 03 '12 at 19:54
  • @JonathanLeffler Yeah, I know - but I kept the `6-6` in the example the show what it would look like to use a wider-range of columns. For instance, if the OP wanted to skip 5 and 10, he would need `-f-4,6-9,11-`. This may (or may not) be visualized if I collapsed it to just `6`. However, I edited to add an example with sequential columns too - so thank you for the tip =] – newfurniturey Dec 03 '12 at 19:58
34

Sometimes it's easier to think in terms of which fields to exclude.

If the number of fields not being cut (not being retained in the output) is small, it may be easier to use the --complement flag, e.g. to include all fields 1-20 except not 3, 7, and 12 -- do this:

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

Rather than

cut -d, -f-2,4-6,8-11,13-
Chris Johnson
  • 20,650
  • 6
  • 81
  • 80
12

You are able to cut all odd/even columns by using seq:

This would print all odd columns

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

To print all even columns you could use

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

By changing the second number of seq you can specify which columns to be printed.

If the specification which columns to print is more complex you could also use a "one-liner-if-clause" like

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)

This would print all columns from 1 to 5 - you can simply modify the conditions to create more complex conditions to specify weather a column shall be printed.

sge
  • 7,330
  • 1
  • 15
  • 18
  • Using in Mac Os (Darwin): echo 1,2,3,4,5,6,7,8,9,10 | cut -d, -f$(seq -s, 1 2 10) I get this error cut: [-cf] list: values may not include zero but if I run: echo 1,2,3,4,5,6,7,8,9,10 | cut -d, -f1,3,5,7,9 the error disappear. Could someone try to explain this? Why if seq is used gives this error? – Bruce_Warrior Apr 03 '15 at 00:34
  • This is more complicated and less flexible than every other answer on this page. – Chris Johnson Jan 13 '21 at 22:48
4

The same could be done with Perl
Because it uses 0-based-indexing instead of 1-based-indexing, the field values are offset by 1

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

is equivalent to:

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

If the commas are not needed in the output:

perl -F, -lane 'print "@F[1..3,5..9,11..19]"'
Chris Koknat
  • 3,305
  • 2
  • 29
  • 30