60

I know how to select a field from a line using the cut command. For instance, given the following data:

a,b,c,d,e
f,g,h,i,j
k,l,m,n,o

This command:

cut -d, -f2 # returns the second field of the input line

Returns:

b
g
l

My question: How can I select the second field counting from the end? In the previous example, the result would be:

d
i
n
ssn
  • 703
  • 1
  • 5
  • 6

3 Answers3

86

Reverse the input before and after cut with rev:

<infile rev | cut -d, -f2 | rev

Output:

d
i
n
Thor
  • 17,182
20

Try doing this with :

awk -F, '{print $(NF-1)}' file.txt

Or using :

perl -F, -lane 'print $F[-2]' file.txt

Or using (thanks manatwork) :

ruby -F, -lane 'print $F[-2]' file.txt

Or using bash (thanks manatwork) :

while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt

Or using :

cat file.txt |
python -c $'import sys\nfor line in sys.stdin:\tprint(line.split(",")[-2])'
  • 1
    bash not needs fixed column count for this: while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt. – manatwork Feb 13 '13 at 15:03
  • 1
    BTW, your third solution also works if you change perl with ruby. – manatwork Feb 13 '13 at 15:08
  • Thanks, ruby added, bash edited. – Gilles Quénot Feb 13 '13 at 15:39
  • 1
    If the 4th field may start with - or (depending on the environment, shell, or how the shell was compiled), may contain backslash characters, then echo is not an option. Why do you need to concatenate file.txt with nothing before feeding it to python!?. You need read -A instead of read -a in ksh93 and zsh. Negative subscripts work in zsh but only in recent versions of ksh93 and bash. In older versions, you can use ${d: -2:1} – Stéphane Chazelas Feb 13 '13 at 16:01
  • 2
    @StephaneChazelas, I think you mean ${d[@]: -2:1} in your last sentence. – manatwork Feb 15 '13 at 08:17
  • @manatwork, yes sorry, thanks for the correction. – Stéphane Chazelas Feb 15 '13 at 10:58
  • I suspected this answer came from someone called Gilles, only it happens to be different from the Gilles I suspected. The same Gilles under a different name perhaps? – vfclists Dec 28 '19 at 19:01
0

Using sed:

sed -E 's/^([^,]*,)*([^,]*)(,[^,]*){1}$/\2/' infile

Output:

d
i
n

Explanation

  • ([^,]*,)* matches any number of non-comma charecter followed by a comma, i.e. any number of columns.
  • ([^,]*) matches a column.
  • (,[^,]*){1} matches one column at the end, if you change the quantifier {1} to {2} it matches the third column from the end etc.
Thor
  • 17,182