Come tagliare (selezionare) un campo dal conteggio delle righe di testo dalla fine?


32

So come selezionare un campo da una riga usando il comando cut. Ad esempio, dati i seguenti dati:

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

Questo comando:

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

Ritorna:

b
g
l

La mia domanda: come posso selezionare il secondo conteggio dei campi dalla fine? Nell'esempio precedente, il risultato sarebbe:

d
i
n

Risposte:


52

Invertire l'input prima e dopo cutcon rev:

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

Produzione:

d
i
n

1
Ho molti piccoli frammenti nella mia cartella bin. rcut è proprio per questo: #! / bin / bash rev | tagliare "$ @" | rev
John Allsup

2
È un peccato che cutnon si possano prendere indici di campo negativi (come Python).
Keith Devens,

10

Prova a farlo con :

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

O usando :

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

O usando (grazie manatwork):

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

O usando bash(grazie 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])'

1
bashNon ha bisogno di conteggio di colonna fissa per questo: while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt.
arte

1
A proposito, la tua terza soluzione funziona anche se cambi perlcon ruby.
arte

Grazie, rubyaggiunto, bashmodificato.
Gilles Quenot,

1
Se il quarto campo può iniziare con -o (a seconda dell'ambiente, della shell o di come è stata compilata la shell), può contenere caratteri di barra rovesciata, quindi echonon è un'opzione. Perché non devi catentrare in contatto file.txtcon nulla prima di dargli da mangiare python!?. È necessario read -Ainvece di read -ain ksh93e zsh. Gli indici negativi funzionano in zshma solo nelle versioni recenti di ksh93e bash. Nelle versioni precedenti, è possibile utilizzare${d: -2:1}
Stéphane Chazelas il

2
@StephaneChazelas, penso che intendi ${d[@]: -2:1}nella tua ultima frase.
arte

0

Usando sed:

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

Produzione:

d
i
n

Spiegazione

  • ([^,]*,)* corrisponde a qualsiasi numero di caratteri non virgola seguito da una virgola, ovvero qualsiasi numero di colonne.
  • ([^,]*) corrisponde a una colonna.
  • (,[^,]*){1}corrisponde a una colonna alla fine, se si modifica il quantificatore {1}in {2}esso corrisponde alla seconda colonna dalla fine ecc.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.