sort
จัดเรียงตัวเลขสองประเภท นี่มาจากหน้าคน:
-g, --general-numeric-sort
compare according to general numerical value
-n, --numeric-sort
compare according to string numerical value
อะไรคือความแตกต่าง?
sort
จัดเรียงตัวเลขสองประเภท นี่มาจากหน้าคน:
-g, --general-numeric-sort
compare according to general numerical value
-n, --numeric-sort
compare according to string numerical value
อะไรคือความแตกต่าง?
คำตอบ:
การเรียงลำดับตัวเลขทั่วไปจะเปรียบเทียบตัวเลขเป็นตัวเลขซึ่งช่วยให้สัญกรณ์ทางวิทยาศาสตร์เช่น 1.234E10 แต่ช้ากว่าและอาจมีข้อผิดพลาดในการปัดเศษ (1.2345678 อาจมาหลัง 1.2345679) การเรียงลำดับตัวเลขเป็นเพียงการเรียงตัวอักษรปกติที่รู้ว่า 10 มาหลัง 9
ดูhttp://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
'-g' '--general-numeric-sort' '--sort = general-numeric' เรียงลำดับตัวเลขโดยใช้ฟังก์ชัน C มาตรฐานเพื่อแปลงคำนำหน้าของแต่ละบรรทัดให้เป็นเลขทศนิยมที่มีความแม่นยำสองเท่า ซึ่งทำให้สามารถระบุตัวเลขทศนิยมในสัญกรณ์วิทยาศาสตร์เช่น 1.0e-34 และ 10e100 โลแคล LC_NUMERIC กำหนดอักขระจุดทศนิยม อย่ารายงานข้อผิดพลาดล้นขาดหรือเกิด Conversion ใช้ลำดับการเรียงต่อไปนี้: เส้นที่ไม่ได้ขึ้นต้นด้วยตัวเลข (ทั้งหมดถือว่าเท่ากัน) NaN (ค่า“ ไม่ใช่ตัวเลข” ในเลขคณิตทศนิยมของ IEEE) ในลำดับที่สอดคล้องกัน แต่ขึ้นอยู่กับเครื่อง ลบอินฟินิตี้ ตัวเลข จำกัด ตามลำดับตัวเลขจากน้อยไปมาก (โดยมี -0 และ +0 เท่ากัน) บวกอินฟินิตี้
ใช้ตัวเลือกนี้เฉพาะในกรณีที่ไม่มีทางเลือกอื่น ช้ากว่า --numeric-sort (-n) มากและอาจสูญเสียข้อมูลเมื่อแปลงเป็นทศนิยม
'-n' '--numeric-sort' '--sort = numeric' เรียงลำดับตัวเลข ตัวเลขเริ่มต้นแต่ละบรรทัดและประกอบด้วยช่องว่างที่เป็นทางเลือกเครื่องหมาย '-' ที่เป็นทางเลือกและตัวเลขที่เป็นศูนย์หรือมากกว่าซึ่งอาจคั่นด้วยตัวคั่นหลายพันตัวเลือกตามด้วยอักขระจุดทศนิยมและตัวเลขศูนย์หรือมากกว่า ตัวเลขว่างจะถือว่าเป็น "0" โลแคล LC_NUMERIC ระบุอักขระจุดทศนิยมและตัวคั่นหลักพัน ตามค่าเริ่มต้นช่องว่างคือช่องว่างหรือแท็บ แต่โลแคล LC_CTYPE สามารถเปลี่ยนแปลงสิ่งนี้ได้
การเปรียบเทียบเป็นสิ่งที่แน่นอน ไม่มีข้อผิดพลาดในการปัดเศษ
ไม่รู้จักทั้งเครื่องหมาย '+' นำหน้าหรือเลขชี้กำลัง หากต้องการเปรียบเทียบสตริงดังกล่าวในเชิงตัวเลขให้ใช้ตัวเลือก --general-numeric-sort (-g)
-k3.2n
หรือ-k3.2g
เป็นการเรียงลำดับR10
ก่อนหน้าR2
นี้ การจัดเรียงเป็นศัพท์ไม่ใช่ตัวเลข ฉันคาดหวังว่ามันจะถือว่าฟิลด์ตั้งแต่อักขระตัวที่สองเป็นต้นไปเป็นตัวเลข
sort
จำเพาะที่สำคัญ เป็นไบแซนไทน์อย่างแท้จริง - สั้น ๆ คือ: ช่องว่างที่อยู่ข้างหน้าฟิลด์ถือเป็นส่วนหนึ่งของฟิลด์ดังนั้นถ่าน ดัชนี 1 ชี้ไปยังช่องว่าง (แรก) ที่อยู่ข้างหน้าฟิลด์ไม่ใช่อักขระตัวแรกที่แท้จริงของฟิลด์ ต่อท้ายตัวอักษร ดัชนีด้วยb
เพื่อแก้ไขปัญหานี้เช่น: -k 3.2bn,3
(โปรดทราบว่าตัวเลือกส่วนกลาง ไม่ทำงานในกรณีนี้) นอกจากนี้ยังทราบเพิ่มซึ่งทำให้มั่นใจได้ว่ามีเพียงสนามที่ 3 จะใช้ - ไม่ดัชนีฟิลด์ที่ 2 ที่เหลือของสายทั้งหมดถูกนำมาใช้ -b
,3
คุณควรระมัดระวังกับสถานที่ของคุณ ตัวอย่างเช่นคุณอาจต้องการจัดเรียงตัวเลขลอยตัว (เช่น 2.2) ในขณะที่ภาษาของคุณอาจคาดหวังให้ใช้เครื่องหมายจุลภาค (เช่น 2,2)
ตามที่รายงานในฟอรัมนี้คุณอาจพบผลลัพธ์ที่ไม่ถูกต้องโดยใช้แฟล็ก -n หรือ -g
ในกรณีของฉันฉันใช้:
LC_ALL=C sort -k 6,6n file
เพื่อจัดเรียงคอลัมน์ที่ 6 ที่มี:
2.5
3.7
1.4
เพื่อให้ได้
1.4
2.5
3.7
-n
จำเครื่องหมายจุลภาคเป็นตัวคั่นหลักพันได้ -“ 1,000” จะถือว่าเหมือนกับ“ 1”
sort
ใช้ตรรกะคำนำหน้าที่ยาวที่สุด: ส่วนที่ยาวที่สุดของบรรทัด / คีย์ที่รับรู้ว่าใช้ตัวเลข ในสถานที่ที่ใช้เป็นตัวละครกี่ก็จะหยุดอ่านที่.
,
LC_ALL=C
เป็นตัวเลือกที่แข็งแกร่งที่สุด อย่างไรก็ตามหากLC_ALL
ไม่ได้เดิมพันชุดLANG=C
ก็จะได้ผลเช่นกัน
LANG=C sort -k 6,6n file
ทั้งง่ายกว่าและยังแปลผลของการตั้งค่าตัวแปรสภาพแวดล้อมLANG
ให้เป็นคำสั่งเฉพาะ
นอกเหนือจากคำตอบที่ยอมรับซึ่งกล่าวถึง-g
อนุญาตให้ใช้สัญกรณ์ทางวิทยาศาสตร์แล้วฉันต้องการแสดงให้เห็นถึงส่วนที่น่าจะเป็นสาเหตุของพฤติกรรมที่ไม่พึงปรารถนา
ด้วย-g
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -g myfile
baa
--inf
--inf
--inf-
--inf--
--inf-a
--nnf
nnf--
nnn
tnan
zoo
naN
Nana
nani lol
-inf
-inf--
-11
-2
-1
1
+1
2
+2
0xa
11
+11
inf
ดูzoo
สามสิ่งสำคัญที่นี่:
บรรทัดเริ่มต้นด้วยNAN
(เช่นNana
และnani lol
) หรือ-INF
(ขีดเดียวไม่ใช่--INF
) เลื่อนไปที่จุดสิ้นสุด แต่ก่อนหลัก ในขณะที่INF
การย้ายไปที่ผ่านมาหลังจากที่ตัวเลขเพราะมันหมายถึงอินฟินิตี้
NAN
, INF
และ-INF
เป็นกรณีตาย
สายเสมอละเว้นช่องว่างจากด้านข้างของทั้งNAN
, INF
, -INF
(ไม่LC_CTYPE
) ตัวอักษรอื่น ๆ อาจละเว้นช่องว่างจากด้านใดด้านหนึ่งขึ้นอยู่กับโลแคลLC_COLLATE
(เช่นLC_COLLATE=fr_FR.UTF-8
ละเว้น แต่LC_COLLATE=us_EN.UTF-8
ไม่เพิกเฉย)
ดังนั้นหากคุณกำลังเรียงลำดับตัวอักษรและตัวเลขพล-g
แล้วคุณอาจไม่ต้องการ หากคุณต้องการเปรียบเทียบค่าทางวิทยาศาสตร์จริงๆ-g
แล้วคุณอาจต้องการที่จะดึงตัวอักษรและข้อมูลที่เป็นตัวเลขและทำเปรียบเทียบแยกต่างหาก
หากคุณต้องการเพียงตัวเลขธรรมดา (เช่น1, -1
) การเรียงลำดับและรู้สึกว่า0x/E/+ sorting
ไม่สำคัญให้ใช้ให้-n
เพียงพอ:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-1000
-22
-13
-11
-010
-10
-5
-2
-1
-0.2
-0.12
-0.11
-0.1
0x1
0x11
0xb
+1
+11
+2
-a
-aa
--aa
-aaa
-b
baa
BAA
bbb
+ignore
inf
-inf
--inf
--inf
--inf-
--inf--
-inf--
--inf-a
naN
Nana
nani lol
--nnf
nnf--
nnn
None
uum
Zero cool
-zzz
1
1.1
1.234E10
5
11
อย่างใดอย่างหนึ่ง-g
หรือ-n
ให้ตระหนักถึงผลกระทบที่เกิดเหตุ คุณอาจต้องการที่จะระบุLC_NUMERIC
เป็นus_EN.UTF-8
เพื่อหลีกเลี่ยงการ fr_FR.UTF-8 เรียง-
ลอยตัวจำนวนล้มเหลว :
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=fr_FR.UTF-8 sort -n myfile
-10
-5
-2
-1
-1.1
-1.2
-0.1
-0.11
-0.12
-0.2
-a
+b
middle
-wwe
+zoo
1
1.1
ด้วยLC_NUMERIC=en_US.UTF-8
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-10
-5
-2
-1.2
-1.1
-1
-0.2
-0.12
-0.11
-0.1
-a
+b
middle
-wwe
+zoo
1
1.1
หรือLC_NUMERIC=us_EN.UTF-8
จะจัดกลุ่ม+|-|space
กับalpha
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=us_EN.UTF-8 sort -n myfile
-0.1
a
b
a
b
+b
+zoo
-a
-wwe
middle
1
คุณอาจต้องการระบุlocale
เมื่อใช้sort
ถ้าต้องการเขียนสคริปต์แบบพกพา
sort
ไม่ใช่man
หน้า แต่เป็นinfo
หน้า (info sort
)