दो क्षेत्रों पर छाँटने की कोशिश की जा रही है, दूसरा तो पहले


106

मैं कई कॉलमों को छाँटने की कोशिश कर रहा हूँ। परिणाम उम्मीद के मुताबिक नहीं हैं।

यहाँ मेरा डेटा (लोग हैं। 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

निम्नलिखित सही ढंग से काम करता है:

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

लेकिन, निम्नलिखित उम्मीद के मुताबिक काम नहीं करता है:

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

मैं उपनाम और फिर पहले नाम से छाँटने की कोशिश कर रहा था, लेकिन आप देखेंगे कि विलमर्स सही क्रम में नहीं हैं। मैं उपनाम से छाँटने की उम्मीद कर रहा था, और फिर जब उपनाम का मिलान हुआ, तो पहले नाम से छाँटना था।

ऐसा लगता है कि इस बारे में कुछ है कि मुझे यह काम कैसे करना चाहिए मुझे समझ में नहीं आता है। मैं कोर्स का यह दूसरा तरीका (awk का उपयोग करके) कर सकता था, लेकिन मैं सॉर्ट को समझना चाहता हूं।

मैं मैक ओएस एक्स पर मानक बैश शेल का उपयोग कर रहा हूं।

जवाबों:


159

एक प्रमुख विनिर्देशन का -k2अर्थ है 2 पंक्ति से अंत तक सभी क्षेत्रों को ध्यान में रखना। तो Villamor 44पहले खत्म होता है Villamor 50। चूँकि ये दोनों समान नहीं हैं, इसलिए sort -k2 -k1इन दोनों रेखाओं में भेदभाव करने के लिए पहली तुलना पर्याप्त है, और दूसरी तरह की कुंजी -k1को लागू नहीं किया जाता है। यदि दो विल्मोरों की आयु समान होती, -k1तो उन्हें पहले नाम से क्रमबद्ध करना पड़ता।

एक एकल कॉलम के आधार पर, -k2,2कुंजी विनिर्देश के रूप में उपयोग करें । इसका अर्थ है # 2 से # 2 तक के खेतों का उपयोग करना, अर्थात केवल दूसरा क्षेत्र।

sort -k2 -k3 <people.txtबेमानी है: यह इसके बराबर है sort -k2 <people.txt। अंतिम नामों को क्रमबद्ध करने के लिए, फिर पहले नाम, फिर आयु, निम्नलिखित कमांड चलाएँ:

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

या समकक्ष रूप sort -k2,2 -k1 <people.txtसे केवल ये तीन क्षेत्र हैं और विभाजक समान हैं। वास्तव में, आपको एक ही प्रभाव मिलेगा sort -k2,2 <people.txt, क्योंकि sortपूरी लाइन को अंतिम उपाय के रूप में उपयोग किया जाता है जब लाइनों के सबसेट में सभी चाबियाँ समान होती हैं।

यह भी ध्यान दें कि डिफ़ॉल्ट फ़ील्ड विभाजक एक गैर-रिक्त और रिक्त के बीच संक्रमण है, इसलिए कुंजियों में प्रमुख रिक्त स्थान शामिल होंगे (आपके उदाहरण में, पहली पंक्ति के लिए, पहली कुंजी होगी "Emily", लेकिन दूसरी कुंजी है " Bedford"-bविकल्प उन खाली करने के लिए:

sort -b -k2,2 -k1,1

यह bकुंजी स्टार्ट स्पेसिफिकेशन के अंत में ध्वज को जोड़कर प्रति-कुंजी के आधार पर भी किया जा सकता है :

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

लेकिन कुछ को ध्यान में रखना: जैसे ही आप कुंजी विनिर्देशन में एक ऐसा ध्वज जोड़ते हैं, वैश्विक झंडे (जैसे -n, -r...) अब उन पर लागू नहीं होते हैं, इसलिए बेहतर है कि प्रति-कुंजी झंडे और वैश्विक झंडे को मिलाने से बचें।


6
आप इसे किसी न किसी। मैंने मान लिया था (एक खतरनाक बात) कि निर्दिष्ट करना -k1 का अर्थ होगा फ़ील्ड 1, जहाँ फ़ील्ड डिफ़ॉल्ट फ़ील्ड विभाजक (स्पेस) पर समाप्त होती है। लेकिन जैसा कि आप स्पष्ट रूप से इंगित करते हैं, कश्मीर विकल्प आपको उम्मीद करता है कि आप कुंजी के स्टार्ट और स्टॉप पॉइंट को निर्दिष्ट कर सकते हैं, जो एकल फ़ील्ड हो भी सकता है और नहीं भी। आपका समाधान पूरी तरह से काम करता है, और इससे भी महत्वपूर्ण बात, मैं स्पष्ट हूं कि यह ऐसा क्यों करता है। बहुत धन्यवाद।
हैरी

यह बहुत बड़ा है। KEYDEF के बारे में कई अन्य स्रोतों के बारे में -k1 -k2 के बारे में बात करता है कि प्रारूप में COMMA के महत्व को सीमित करने के बिना प्रत्येक छंटनी चरण में कौन से कॉलम को माना जाता है। जब तक मुझे यह जवाब नहीं मिला, मैं घंटों तक इस पर अटका रहा। और मैन पेज यहाँ भ्रमित कर रहा है। यह नहीं समझाता है कि "प्रारंभ और रोकें" स्थान अल्पविराम संकेतन के साथ निर्दिष्ट हैं। धन्यवाद!
जेसन रोहरर

16

GNU के साथ sortआप इसे इस तरह करते हैं, MacOS के बारे में निश्चित नहीं:

sort -k2,2 -k1 <people.txt

टिप्पणी के अनुसार अद्यतन करें । से उद्धृत 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.

4
क्या आप इस विचित्र संकेतन की व्याख्या कर सकते हैं?
स्काइ

1
यह मुझे सही लाइनों के साथ सोच रहा था - इसके लिए धन्यवाद। लेकिन आपको दूसरे -k के लिए स्टॉप पॉइंट को निर्दिष्ट करने की आवश्यकता नहीं है। वह है -k2,2 -k1,1 अन्यथा स्टॉप पॉइंट लाइन के अंत के रूप में लिया जाता है?
हैरी

@TonyBedford, सही है। लेकिन स्टॉप स्थिति को निर्दिष्ट नहीं करने से आपके वर्तमान इनपुट के लिए परिणाम नहीं बदलेगा, लेकिन जब आप कभी भी समान फ़ील्ड 2 और 1. के साथ कई लाइनें लगाएंगे, तो मैं इस पर बल दूंगा, इसलिए मैं अंतिम -kको उतना ही शामिल करने की अनुमति देना पसंद करता हूं ।
मैनटवर्क

1
@ मैनटवर्क जो आवश्यक नहीं होना चाहिए; यदि सभी निर्दिष्ट फ़ील्ड समान sortतुलना करते हैं , तो पूरी लाइन की तुलना करेंगे। या जीएनयू के साथ sortआप -sस्थिर प्रकार के लिए उपयोग कर सकते हैं ।
अगुरार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.