it-swarm-eu.dev

Pokus o řazení na dvou polích, druhý pak první

Snažím se třídit do několika sloupců. Výsledky nejsou očekávané.

Zde jsou moje údaje (people.txt):

Simon Strange 62
Pete Brown 37
Mark Brown 46
Stefan Heinz 52
Tony Bedford 50
John Strange 51
Fred Bloggs 22
James Bedford 21
Emily Bedford 18
Ana Villamor 44
Alice Villamor 50
Francis Chepstow 56

Následující funguje správně:

bash-3.2$ sort -k2 -k3 <people.txt                                                                                                                    
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

Následující postup však nefunguje podle očekávání:

bash-3.2$ sort -k2 -k1 <people.txt                                        
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

Snažil jsem se třídit podle příjmení a potom podle křestního jména, ale uvidíte, že Villamors nejsou ve správném pořadí. Doufal jsem, že se seřadí podle příjmení, a pak, když se shodují příjmení, seřadí se podle křestního jména.

Zdá se, že existuje něco o tom, jak by to mělo fungovat, kterému nerozumím. Mohl bych to udělat jiným způsobem (pomocí awk), ale chci pochopit druh.

Používám standardní Bash Shell na Mac OS X.

111
Harry

Klíčová specifikace jako -k2 znamená vzít v úvahu všechna pole od 2 do konce řádku. Tak Villamor 44 skončí před Villamor 50. Protože tyto dva nejsou stejné, první srovnání v sort -k2 -k1 stačí k rozlišení těchto dvou řádků a druhý klíč řazení -k1 není vyvoláno. Pokud měli oba Villamors stejný věk, -k1 by způsobilo, že by byly seřazeny podle křestního jména.

Chcete-li seřadit podle jednoho sloupce, použijte -k2,2 jako specifikace klíče. To znamená použít pole od # 2 do # 2, tj. Pouze druhé pole.

sort -k2 -k3 <people.txt je nadbytečné: je ekvivalentní s sort -k2 <people.txt. Chcete-li seřadit podle příjmení, potom křestních jmen a věku, spusťte následující příkaz:

sort -k2,2 -k1,1 <people.txt

nebo rovnocenně sort -k2,2 -k1 <people.txt protože existují pouze tato tři pole a oddělovače jsou stejné. Ve skutečnosti získáte stejný efekt od sort -k2,2 <people.txt, protože sort používá celý řádek jako poslední možnost, když jsou všechny klíče v podmnožině řádků identické.

Také si všimněte, že výchozí oddělovač polí je přechod mezi neprázdným a prázdným, takže klíče budou zahrnovat úvodní mezery (v příkladu pro první řádek bude první klávesa "Emily", ale druhý klíč " Bedford". Přidat -b možnost odstranit tyto mezery:

sort -b -k2,2 -k1,1

Lze to také provést na základě jednotlivých klíčů přidáním příznaku b na konci specifikace začátku klíče:

sort -k2b,2 -k1,1 <people.txt

Ale co je třeba mít na paměti: jakmile přidáte jeden takový příznak ke klíčové specifikaci, globální příznaky (jako -n, -r...) se na ně již nevztahují, takže je lepší vyhnout se míchání vlajek na klíč a globálních vlajek.

S GNU sort to děláte takto, nevíte o MacOS:

sort -k2,2 -k1 <people.txt

Aktualizace podle komentáře. Citováno z man sort:

   -k, --key=KEYDEF
          sort via a key; KEYDEF gives location and type

   KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where
   F is a field number and C a character position in the field; both are
   Origin 1, and the stop position defaults to the line's end.
16
manatwork