হেক্স মান অনুসারে বাছাই করুন


14

কোর্টিলস ব্যবহার করে sort, আমি কীভাবে একটি হেক্সাডেসিমাল মান (ক্ষেত্র) দ্বারা সংখ্যার অনুসারে বাছাই করতে পারি? আমি লাইন বরাবর কিছু প্রত্যাশা ছিল

sort -k3,3x file_to_sort

যাইহোক, যেমন একটি xবিদ্যমান নেই।

সম্পাদনা করুন: আমি এখনও অবধি সেরা সমাধানটি নিয়ে এসেছি:

{ echo ibase=16; cut -d' ' -f3 file_to_sort; } |
  bc | paste -d: - file_to_sort | sort -t: -k1,1n | cut -d: -f2-

যেখানে cut -d' ' -f3অনুসন্ধান ক্ষেত্রটি বিচ্ছিন্ন করে (এটি হ'ল -k3,3এটি অবশ্যই পরিবর্তিত হতে পারে) এবং bcদশমিক রূপান্তর করে ( 0xপ্রিফিক্স ছাড়াই আপার-কেস হেক্স প্রয়োজন, আমার কেসের সাথে মেলে)। তারপরে আমি কলামগুলিতে যোগদান করি, বাছাই করি এবং ভাগ করি।


-k3,3? আপনার 0x এবং একই দৈর্ঘ্যের সমস্তগুলি সহ হেক্স নুবারস রয়েছে? উপরের / ছোট হাতের মিশ্রণ নেই? যদি হ্যাঁ হয় তবে স্ট্রিং হিসাবে ব্যাখ্যা করার সাথে সাথে এগুলি ঠিক সাজানো উচিত। হতে পারে আপনি আমাদের কিছু উদাহরণ ডেটা দেখাতে পারেন?

@ ইয়েতি: দুর্ভাগ্যক্রমে, না।
স্টিফান

বৈশিষ্ট্যটির অনুরোধ: list.gnu.org/archive/html/coreutils/2017-08/msg00035.html
Ciro

উত্তর:


5

এর মধ্যে একটি সমাধান perl:

$ perl -anle '
    push @h, [$F[-1],$_];
    END {
        print for map  { $_->[0] }
                  sort { $a->[1] <=> $b->[1] }
                  map  { [$_->[1],hex($_->[0])] } @h;
    }
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12

ব্যাখ্যা

  • ফাইল প্রক্রিয়া করার সময়, আমরা অ্যারের একটি অ্যারে তৈরি করি @h, এর প্রতিটি উপাদান একটি অ্যারে রেফারেন্স হয় [$F[-1],$_], প্রথম উপাদানটির সাথে তুলনা করার জন্য হেক্স মান হয় এবং দ্বিতীয় উপাদানটি সম্পূর্ণ লাইন হয়।

  • ইন ENDব্লক, আমরা ব্যবহার Schwartzian রুপান্তর :

    • প্রতিটি উপাদান সহ @h, একটি বেনামে অ্যারে তৈরি করুন, সম্পূর্ণ লাইন ( $_->[1]প্রতিটি অ্যারের দ্বিতীয় উপাদান রেফ ইন @h) এবং তুলনা করার জন্য হেক্স মানটি ধারণ করেhex($_->[0])]

    • হেক্স মানের উপরে অ্যারে বেসের উপরে বাছাই করুন $a->[1] <=> $b->[1]

    • সাজানো অ্যারেতে প্রতিটি অ্যারের রেফার প্রথম উপাদান পান map { $_->[0] } তারপরে ফলাফলটি মুদ্রণ করুন।

হালনাগাদ

@ জোসেফ আর এর পরামর্শে, শোয়ার্টজিয়ান ট্রান্সফর্ম ব্যবহার না করে:

$ perl -anle '
    push @h, [hex($F[-1]),$_];
    END {
        print $_->[1] for
            sort { $a->[0] <=> $b->[0] } @h;
    }
' file

আপডেট 2

স্টিফানের মন্তব্য পড়ার পরে, আমি মনে করি এটি কল করতে পারে direct:

$ perl -e '
    print sort {hex((split(/\s+/,$a))[-1]) <=> hex((split(/\s+/,$b))[-1])} <>;
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12

+1 টি কিন্তু কেন শুধু: print for sort { hex $a->[-1] <=> hex $b->[-1] } @h? hexঅপারেটর কমই ব্যয়বহুল একটি Schwartzian পরোয়ানা যথেষ্ট, তাই নয় কি?
জোসেফ আর।

@ জোসেফআর: সম্ভবত, তবে একজন শোয়ার্টজিয়ান আরও নমনীয় এবং সব ক্ষেত্রেই কাজ করেন। আমি মনে করি প্রক্রিয়া চলাকালীন হেক্স মানটি গণনা করে আমরা আরও একটি সমাধান পেতে পারি, শিগগিরই আমার উত্তর আপডেট করব।
cuonglm

শীতল সমাধান। এই প্যাটার্নটির কোনও নাম ছিল তা জানতেন না: সাজসজ্জা-সাজান-আনকোরেট। আমার মন্তব্য উপরে দেখুন।
স্টেফান

@ স্টেফান: আমার আপডেট হওয়া উত্তরটি দেখুন।
কিউংলম

@ জ্ঞাক: হ্যাঁ, আপনার ২ য় আপডেট অবশ্যই সরাসরি সংযুক্ত হিসাবে যোগ্যতা অর্জন করবে। আমার প্রাথমিক কল্পনা।
স্টিফান

6

আমি এই উদাহরণ ডেটা ব্যবহার করি:

1 hdh d12
2 ukr 9f
3 ezh ae
4 jjk 7
5 hhf 25

দশমিক আকারে সাজানোর ক্ষেত্রটি সহ এই ডেটার একটি নতুন সংস্করণ তৈরি করার ধারণা The অর্থাৎ awkএটিকে রূপান্তরিত করে, প্রতিটি লাইনে এটিকে সংশোধন করে, ফলাফল সাজানো হয় এবং শেষ পদক্ষেপ হিসাবে যুক্ত ক্ষেত্রটি সরানো হয়:

awk '{val="0x" $3; sub("^0x0x","0x",val); print strtonum(val),$0 ;}' file | 
  sort -n | 
  sed 's/^[^ ]* //'

এই ফলাফলের ফলাফল:

4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12

1
ধন্যবাদ, বেশ দুর্দান্ত সমাধান। দুঃখিত যে আমি আমার সম্পাদনাটি আগে পোস্ট করি নি, এটি কাট + পেস্ট ব্যবহার করে অনুরূপ পদ্ধতির অনুসরণ করে। যদিও আমি আরও সরাসরি সমাধানের জন্য আশা করছিলাম ...
স্টেফান

@ স্টেফান "প্রত্যক্ষ" হিসাবে কী গণনা করা হয়? সমাধান কি ব্যবহার করতে হবে sort?
জোসেফ আর।

@ জোসেফ "" প্রত্যক্ষ "হিসাবে গণ্য কি?" সঠিক প্রশ্ন। মূলত এখন পর্যন্ত সমস্ত সমাধান (হউকের, নীচের জ্ঞানকের এবং আমার) একইরকম কিছু করে: হেক্স মানটি ডিকোড করুন, ফলাফলগুলিকে লাইনের সাথে সংযুক্ত করুন, এটি অনুসারে বাছাই করুন এবং এটি সরান। আমি সজ্জা-সাজানোর-আনকোটর প্যাটার্নটি ব্যবহার না করে এমন কিছু সন্ধান করছিলাম । উভয় সমাধান আমার চেয়ে উন্নত, পাইপলাইনে সেই তে কাজ করে। আমি এটিকে বেছে নিয়েছি কারণ আমি এই জাতীয় কাজের জন্য পার্লের চেয়ে ব্যক্তিগতভাবে বরং বিশ্রী (ছোট হাতুড়ি) ব্যবহার করব।
স্টেফান

গনুকের দ্বিতীয় আপডেটের কারণে আমি নীচে আমার উত্তরটি 3 টি সরানো হয়েছে।
স্টিফান

1

অভিযোজিত: http://www.unix.com/302548935-post6.html?s=b4b6b3ed50b6831717f6429113302ad6 থেকে

: ফাইল টু করুনঃ:

6F993B
954B29
A23F2F
BFA91D
C68C15
8F322F
5A6D40
6D512C
9D9D63
B4B823
A0641C
A79716
A18518

COMMAND:

awk '{printf("%050s\t%s\n", toupper($0), $0)}' file-to-sort | LC_COLLATE=C sort -k1,1 | cut -f2

আউটপুট:

C68C15
BFA91D
B4B823
A79716
A23F2F
A18518
A0641C
9D9D63
954B29
8F322F
6F993B
6D512C
5A6D40

- কোথাও স্পর্শক ($ 0) ছোট হাতের অক্ষরগুলিকে "আপগ্রেড" করে যাতে তারা প্রথমে সাজান (নিশ্চিত যে এটি এখনও প্রয়োজনীয়?)


1

ইনপুট

$ cat /tmp/input
0x45 aaa 333
0x50 dd 33
0x4 bbbb 444
0x456 cc 22
0x5 eee 1111

একটি লাইনার বাছাই করা হচ্ছে

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1 | cut -f2- -d' '
0x4 bbbb 444
0x5 eee 1111
0x45 aaa 333
0x50 dd 33
0x456 cc 22

ধাপে ধাপে বাছাই করা হচ্ছে

পদক্ষেপ 1: হেক্স সংখ্যার দশমিক উপস্থাপনা সহ একটি নতুন প্রথম কলাম যুক্ত করুন।

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input 
69 0x45 aaa 333
80 0x50 dd 33
4 0x4 bbbb 444
1110 0x456 cc 22
5 0x5 eee 1111

পদক্ষেপ 2: প্রথম ক্ষেত্রগুলিতে সংখ্যাগুলি লাইনগুলি বাছাই করুন।

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1
4 0x4 bbbb 444
5 0x5 eee 1111
69 0x45 aaa 333
80 0x50 dd 33
1110 0x456 cc 22

পদক্ষেপ 3: প্রথম কলামটি সরান।

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1 | cut -f2- -d' '
0x4 bbbb 444
0x5 eee 1111
0x45 aaa 333
0x50 dd 33
0x456 cc 22
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.