जीएनयू क्रमबद्ध सॉर्ट करता है जब सॉर्ट क्रम क्रम नहीं जानता है


18

मेरे पास एक दो-स्तंभ फ़ाइल है; फ़ाइल को उस तरह से सॉर्ट किया जाता है जैसा मैं पहले से ही कॉलम 1 पर चाहता हूं। मैं प्रत्येक कॉलम 1 श्रेणी के भीतर कॉलम 2 पर सॉर्ट करना चाहूंगा। हालाँकि, sortस्तंभ 1 के क्रम क्रम को नहीं समझता है।

सामान्य तरीका (स्टैक पर इसी तरह के सवालों से) यह होगा:

sort --stable -k1,1 -k2,2n

लेकिन मैं k1 पर सॉर्ट निर्दिष्ट नहीं कर सकता, क्योंकि यह मनमाना है।

उदाहरण इनपुट:

C 2
C 1
A 2
A 1
B 2 
B 1

और उत्पादन:

C 1
C 2
A 1
A 2
B 1 
B 2

जवाबों:


20

आप प्रत्येक ब्लॉक के लिए एक नया प्रकार शुरू करने के लिए awk का उपयोग कर सकते हैं:

% awk -v cmd="sort -k2,2" '$1 != prev {close(cmd); prev=$1} {print | cmd}' foo
C 1
C 2
A 1
A 2
B 1
B 2
  • $1 != prev {close(cmd); prev=$1} - जब बचाया मूल्य अलग है, तो हमारे पास एक नया ब्लॉक है, इसलिए हम किसी भी पहले शुरू किए गए को बंद कर देते हैं sort
  • {print | "sort -k2,2"}'उत्पादन को पाइप करता है sort, इसे शुरू कर रहा है अगर यह पहले से ही नहीं चल रहा है (awk इसे शुरू होने वाले कमांड का ट्रैक रख सकता है)

2
awk वास्तव में अविश्वसनीय है। मुझे यह बहुत पसंद है कि मैं क्या उम्मीद कर रहा था, जो एक अजीब सजावट-प्रकार-अघोषित था!
— इवान बेन

मैंने इसके उत्तर की तुलना बनाम दूसरे उत्तर की तुलना करने की कोशिश की, निश्चित नहीं कि यह अधिक संसाधनों का उपयोग क्यों करता है ... कोई विचार? gist.github.com/EvanTheB/5b64eafb84eeaf51c289295ac06e1b0b
— इवान बेन

आपने कुल कितने रन बनाए?
— मुरु

मैंने कोई औसत नहीं किया, लेकिन मैं लगातार दोहराता हूं और जांच कर रहा हूं।
— इवान बेन

यहाँ एक ऐसी ही फाइल है जो मैं उपयोग कर रहा हूँ अगर आप जांच करना चाहते हैं:seq 30 | xargs -L1 bash -cs 'yes $1 | head -1000000 | paste - <(seq 1000000) | shuf' bash
— इवान बेने

12

आप एक श्वार्ट्ज़ियन ट्रांसफ़ॉर्म का उपयोग कर सकते हैं (यह मूल रूप से सजा-छाँटा-अघोषित दृष्टिकोण है जिसे आपने टिप्पणी में बदल दिया है, लेकिन संभवत: एक एकल आह्वान का उपयोग करने के कारण मूरू के ठीक उत्तर की तुलना में अधिक प्रदर्शन करने वाला) एक sortसे अधिक का उपयोग करते हुए awkएक उपसर्ग कॉलम का उपयोग कर रहा है। पहले कॉलम में मूल्य में बदलाव के साथ वेतन वृद्धि, उपसर्ग कॉलम के बाद "दूसरा" कॉलम (जिसकी क्रमिक स्थिति 3उपसर्ग कॉलम की उपस्थिति के कारण अस्थायी रूप से स्थानांतरित हो गई है) के आधार पर छाँटें , और अंत में उपसर्ग कॉलम से छुटकारा पाएं

awk '{print ($1 in a? c+0: ++c)"\t" $0; a[$1]}' file | sort -k1,1n  -k3,3 | cut -f 2-

मुझे आश्चर्य है, लेकिन आप सही हैं, यह अन्य उत्तर की तुलना में तेज था! मेरी 100 मिलियन लाइन फ़ाइल (~ 30 यूनीक पहले कॉलम) पर 3 मिनट बनाम 2 मिनट।
— इवान बेन

1
पहले कॉलम से अद्वितीय कुंजी की एक सरणी रखने की आवश्यकता नहीं है। मुझे लगता है कि वर्तमान लाइन के पहले कॉलम की तुलना पिछले के मुकाबले करने के लिए पर्याप्त होना चाहिए।
— Kusalananda

कुछ ऐसा awk -v OFS="\t" '$1 != prev { key++ } { print key, $0; prev = $1 }(अप्रकाशित)।
— Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.