¿Cómo cortar (seleccionar) un campo de la línea de texto contando desde el final?

32

Sé cómo seleccionar un campo de una línea usando el comando de corte. Por ejemplo, dados los siguientes datos:

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

Este comando:

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

Devoluciones:

b
g
l

Mi pregunta: ¿Cómo puedo seleccionar el segundo campo contando desde el final? En el ejemplo anterior, el resultado sería:

d
i
n
ssn
fuente

Respuestas:

52

Invierta la entrada antes y después cutcon rev:

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

Salida:

d
i
n
Thor
fuente
1
Tengo muchos fragmentos pequeños en mi carpeta bin. rcut es precisamente para esto: #! / bin / bash rev | cortar "$ @" | rev
John Allsup
2
Es una lástima cutque no pueda tomar índices de campo negativos (como Python).
Keith Devens
10

Intenta hacer esto con :

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

O usando :

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

O usando (gracias manatwork):

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

O usando bash(gracias manatwork):

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

O usando :

cat file.txt |
python -c $'import sys\nfor line in sys.stdin:\tprint(line.split(",")[-2])'
Gilles Quenot
fuente
1
bashNo necesita recuento columna fija para esto: while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt.
manatwork
1
Por cierto, su tercera solución también funciona si cambia perlcon ruby.
manatwork
Gracias, rubyagregado, basheditado.
Gilles Quenot
1
Si el cuarto campo puede comenzar con -o (según el entorno, el shell o cómo se compiló el shell), puede contener caracteres de barra invertida, entonces echono es una opción. ¿Por qué necesitas catconatear file.txtcon nada antes de alimentarlo python? Necesitas en read -Alugar de read -aen ksh93y zsh. Los subíndices negativos funcionan zshpero solo en versiones recientes de ksh93y bash. En versiones anteriores, puede usar${d: -2:1}
Stéphane Chazelas
2
@StephaneChazelas, creo que te refieres ${d[@]: -2:1}a tu última oración.
manatwork
0

Usando sed:

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

Salida:

d
i
n

Explicación

  • ([^,]*,)* coincide con cualquier número de caracteres que no sean comas seguidos de una coma, es decir, cualquier número de columnas.
  • ([^,]*) coincide con una columna
  • (,[^,]*){1}coincide con una columna al final, si cambia el cuantificador {1}para {2}que coincida con la segunda columna del extremo etc.
Thor
fuente