haluk
haluk

Reputation: 1168

How to cut first n and last n columns?

How can I cut off the first n and the last n columns from a tab delimited file?

I tried this to cut first n column. But I have no idea to combine first and last n column

cut -f 1-10 -d "<CTR>v <TAB>" filename

Upvotes: 96

Views: 158088

Answers (9)

late2party
late2party

Reputation: 1

To answer the second part of the question, if you have the non-standard 'rev' (reverse) command available, simply reverse the line, then cut from the nth column to the end, then reverse back. e.g. '... | rev | cut -d. -f 2- | rev'

So to combine this is the first part of your question you would cut the first 'n' columns before the first rev.

Upvotes: 0

Yu Tao
Yu Tao

Reputation: 798

Use

cut -b COLUMN_N_BEGINS-COLUMN_N_UNTIL INPUT.TXT > OUTPUT.TXT

-f doesn't work if you have "tabs" in the text file.

Upvotes: -1

Mark G.
Mark G.

Reputation: 2978

The first part of your question is easy. As already pointed out, cut accepts omission of either the starting or the ending index of a column range, interpreting this as meaning either “from the start to column n (inclusive)” or “from column n (inclusive) to the end,” respectively:

$ printf 'this:is:a:test' | cut -d: -f-2
this:is
$ printf 'this:is:a:test' | cut -d: -f3-
a:test

It also supports combining ranges. If you want, e.g., the first 3 and the last 2 columns in a row of 7 columns:

$ printf 'foo:bar:baz:qux:quz:quux:quuz' | cut -d: -f-3,6-
foo:bar:baz:quux:quuz

However, the second part of your question can be a bit trickier depending on what kind of input you’re expecting. If by “last n columns” you mean “last n columns (regardless of their indices in the overall row)” (i.e. because you don’t necessarily know how many columns you’re going to find in advance) then sadly this is not possible to accomplish using cut alone. In order to effectively use cut to pull out “the last n columns” in each line, the total number of columns present in each line must be known beforehand, and each line must be consistent in the number of columns it contains.

If you do not know how many “columns” may be present in each line (e.g. because you’re working with input that is not strictly tabular), then you’ll have to use something like awk instead. E.g., to use awk to pull out the last 2 “columns” (awk calls them fields, the number of which can vary per line) from each line of input:

$ 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

Upvotes: 10

kauppi
kauppi

Reputation: 17406

Cut can take several ranges in -f:

Columns up to 4 and from 7 onwards:

cut -f -4,7-

or for fields 1,2,5,6 and from 10 onwards:

cut -f 1,2,5,6,10-

etc

Upvotes: 138

Saurabh
Saurabh

Reputation: 7833

You can cut using following ,
-d: delimiter ,-f for fields
\t used for tab separated fields

cut -d$'\t' -f 1-3,7-

Upvotes: 5

kenorb
kenorb

Reputation: 166359

You can use Bash for that:

while read -a cols; do echo ${cols[@]:0:1} ${cols[@]:1,-1}; done < file.txt

Upvotes: 0

user2009292
user2009292

Reputation: 1

Try the following:

echo a#b#c | awk -F"#" '{$1 = ""; $NF = ""; print}' OFS=""

Upvotes: -1

Dennis Williamson
Dennis Williamson

Reputation: 359955

To use AWK to cut off the first and last fields:

awk '{$1 = ""; $NF = ""; print}' inputfile

Unfortunately, that leaves the field separators, so

aaa bbb ccc

becomes

[space]bbb[space]

To do this using kurumi's answer which won't leave extra spaces, but in a way that's specific to your requirements:

awk '{delim = ""; for (i=2;i<=NF-1;i++) {printf delim "%s", $i; delim = OFS}; printf "\n"}' inputfile

This also fixes a couple of problems in that answer.

To generalize that:

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

Then you can change the number of fields to skip at the beginning or end by changing the variable assignments at the beginning of the command.

Upvotes: 2

kurumi
kurumi

Reputation: 25599

you can use awk, for example, cut off 1st,2nd and last 3 columns

awk '{for(i=3;i<=NF-3;i++} print $i}' file

if you have a programing language such as Ruby (1.9+)

$ ruby -F"\t" -ane 'print $F[2..-3].join("\t")' file

Upvotes: -1

Related Questions