使用 cut 命令删除多个列

给定的输入

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

如果我想削减第5栏,我可以做

cut -d, -f-4,6-

如果我想删除多个非连续的列,如5,7等 有一句话吗?

177826 次浏览

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".

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.

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-

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]"'