2010-09-30 17 views
19

Mam plik tekstowy zawierający ~ 300 tys. Wierszy. Każdy wiersz ma zmienną liczbę pól rozdzielanych przecinkami, z których ostatnia jest gwarantowana liczbowo. Chcę posortować plik według tego ostatniego pola liczbowego. Nie mogę:Bash: sortuj plik tekstowy według ostatniej wartości pola

sort -t, -n -k 2 file.in > file.out 

ponieważ liczba pól w każdym rzędzie nie jest stała. Myślę, że sed, awk może odpowiedź, ale nie jestem pewien jak. Np .:

awk -F, '{print $NF}' file.in 

podaje mi ostatnią wartość kolumny, ale jak użyć tego do posortowania pliku?

Odpowiedz

27

Użyj awk, aby umieścić klawisz numeryczny z przodu. $NF jest ostatnim polem bieżącego rekordu. Sortować. Użyj sed, aby usunąć duplikat klucza.

awk -F, '{ print $NF, $0 }' yourfile | sort -n -k1 | sed 's/^[0-9][0-9]* //' 
+6

Brak potrzeby przekierowania. 'awk -F, '{print $ NF, $ 0}' twój plik' – ghostdog74

0

Może odwrócić pola każdej linii w pliku przed sortowaniem? Coś takiego, jak powinno się robić, o ile przecinki nie są w żaden sposób cytowane. Jeśli jest to pełnoprawny plik CSV (w którym przecinki mogą być cytowane z ukośnikiem odwrotnym lub spacji), potrzebujesz prawdziwego parsera CSV.

2
vim file.in -c '%sort n /.*,\zs/' -c 'saveas file.out' -c 'q' 
+1

Dlaczego nie użyć 'ex' jeśli masz zamiar iść tą drogą? Vim uzyskuje tę konkretną funkcjonalność z "ex". –

+0

'ex' jest po prostu' vim', z opcją '-e'. W tym przypadku tak naprawdę nie ma znaczenia. – Benoit

+0

'ex' poprzedza' vim' (i 'vi') przez dość długi czas. 'vim' może mieć tryb emulacji" ex ", ale nie czyni go' ex'. –

0

Perl jedno-liner:

@lines=<STDIN>;foreach(sort{($a=~/.*,(\d+)/)[0]<=>($b=~/.*,(\d+)/)[0]}@lines){print;} 
0

zamierzam rzucać kopalnię tu jako alternatywa (i nie mogłem uzyskać awk do pracy) :)

przykładowy plik :

Call of Doody       1322 
Seam the Ripper       1329 
Mafia Bots 1       1109 
Chicken Fingers       1243 
Batup Light        1221 
Hunter F Tomcat       1140 
Tober         0833 

Kod:

for i in `sed -e 's/.* \(\d\)*/\1/' file.txt | sort`; do grep $i file.txt; done > file_sort.txt 
0

Python jedno-liner:

python -c "print ''.join(sorted(open('filename'), key=lambda l: int(l.split(',')[-1])))" 
Powiązane problemy