কীভাবে awk '! A [$ 0] ++' কাজ করে?


40

এই ওয়ান-লাইনার প্রাক-বাছাই ছাড়াই পাঠ্য ইনপুট থেকে সদৃশ লাইনগুলি সরিয়ে দেয়।

উদাহরণ স্বরূপ:

$ cat >f
q
w
e
w
r
$ awk '!a[$0]++' <f
q
w
e
r
$ 

ইন্টারনেট পড়তে মূল কোডটি আমি খুঁজে পেয়েছি:

awk '!_[$0]++'

_পার্লের মতো অজানাতে একটি বিশেষ অর্থ বয়ে নিয়েছি বলে এটি আমার কাছে আরও বিচলিত হয়েছিল, তবে এটি কেবল অ্যারের নাম হিসাবে পরিণত হয়েছিল।

এখন, আমি ওয়ান-লাইনারের পিছনে যুক্তিটি বুঝতে পারি: প্রতিটি ইনপুট লাইন একটি হ্যাশ অ্যারেতে একটি কী হিসাবে ব্যবহৃত হয়, সুতরাং, সমাপ্তির পরে, হ্যাশটিতে আগমনের ক্রমে অনন্য লাইন থাকে।

আমি যেটি শিখতে চাই তা হ'ল কীভাবে এই স্বরলিপিটি অর্জক দ্বারা ব্যাখ্যা করা হয়েছে। যেমন ঠুং ঠুং শব্দ ( !) এর অর্থ কী এবং এই কোড স্নিপেটের অন্যান্য উপাদান।

এটা কিভাবে কাজ করে?


শিরোনাম বিভ্রান্তিমূলক, এটি $ 0 (জিরো) হওয়া উচিত, $ o (ও) নয়।
আর্চেমার

2
এটি একটি হ্যাশ হিসাবে, এটি সীমানাবিহীন, সুতরাং "আগমনের ক্রম" আসলে সঠিক নয়।
কেভিন

উত্তর:


35

দেখা যাক,

 !a[$0]++

প্রথম

 a[$0]

আমরা a[$0]( aপুরো ইনপুট লাইনের সাথে অ্যারেরটি $0) কী হিসাবে দেখি look

যদি এটির অস্তিত্ব না থাকে ( !তবে পরীক্ষায় অবহেলা করা সত্য হয়ে উঠবে)

 !a[$0]

আমরা ইনপুট লাইন $0(ডিফল্ট ক্রিয়া) মুদ্রণ করি ।

এছাড়াও, আমরা এতে একটি ( ++) যুক্ত করি a[$0], সুতরাং পরবর্তী সময়টি !a[$0]মিথ্যা হিসাবে মূল্যায়ন করবে।

ভাল লাগল, খুঁজে দাও !! আপনি কোড গল্ফ এক নজর করা উচিত!


1
সুতরাং সারমর্মটি হ'ল: একক উদ্ধৃতিতে প্রকাশিত awkপ্রতিটি ইনপুট লাইনের জন্য পরীক্ষা হিসাবে ব্যবহৃত হয় ; প্রতিবার পরীক্ষা সফল awkহলে কোঁকড়া ধনুর্বন্ধনীগুলিতে ক্রিয়াকলাপ সম্পাদন করে, যা বাদ দেওয়া হয় {print}। ধন্যবাদ!
আলেকজান্ডার শ্যাচব্লিকিন

3
@ আরচেমার: এই উত্তরটি ভুল, আমার দেখুন see
cuonglm

অ্যালেক্সান্দারশেকব্লিকিন ইন awk, ডিফল্ট ক্রিয়াটি {print $0}। এর অর্থ সত্য হিসাবে মূল্যায়ন করা যে কোনও কিছুই এটি ডিফল্ট হিসাবে কার্যকর করে। উদাহরণস্বরূপ awk '1' file, সমস্ত লাইন awk '$1' fileমুদ্রণ করে, সেই সমস্ত রেখাগুলি মুদ্রণ করে যাদের প্রথম ক্ষেত্রটি খালি বা 0, ইত্যাদি নয়
fedorqui

6
@ জ্ঞাক আমি এই উত্তরে কোনও গুরুতর ত্রুটি দেখতে পাচ্ছি না। আপনি যদি এটিই উল্লেখ করছেন, অভিব্যক্তির মান গণনার পরে বর্ধনটি প্রকৃতপক্ষে প্রয়োগ করা হবে। এটি সত্য যে প্রিন্টিংয়ের আগে বর্ধন ঘটে but তবে এটি একটি ছোটখাটো অসম্পূর্ণতা যা মৌলিক ব্যাখ্যাগুলিকে প্রভাবিত করে না।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'


30

প্রক্রিয়াজাতকরণ এখানে:

  • a[$0]: $0এসোসিয়েটিভ অ্যারেতে কীটির মান দেখুন a। এটি উপস্থিত না থাকলে এটি তৈরি করুন।

  • a[$0]++: এর মান বৃদ্ধি করুন a[$0], অভিব্যক্তির মান হিসাবে পুরানো মানটি ফিরিয়ে দিন। তাহলে a[$0], কোন অস্তিত্ব নেই প্রত্যাবর্তন 0এবং বৃদ্ধি a[$0]করার জন্য 1( ++অপারেটর আয় সাংখ্যিক মান)।

  • !a[$0]++: অভিব্যক্তির মান অবহেলা করুন। যদি a[$0]++ফিরে আসে 0, পুরো এক্সপ্রেশনটি সত্য হিসাবে মূল্যায়ন করা হয়, awkসম্পাদিত ডিফল্ট ক্রিয়া করুন print $0। অন্যথায়, পুরো ভাবটি মিথ্যা হিসাবে মূল্যায়ন করা হয়, কারণগুলি awkকিছুই করে না।

তথ্যসূত্র:

এর সাথে gawk, আমরা কোনও স্ক্রিপ্ট ডিবাগ করতে dgawk (বা awk --debugআরও নতুন সংস্করণ সহ) ব্যবহার করতে পারি gawk। প্রথমে, একটি gawkস্ক্রিপ্ট তৈরি করুন , যার নাম test.awk:

BEGIN {                                                                         
    a = 0;                                                                      
    !a++;                                                                       
}

তারপরে চালান:

dgawk -f test.awk

বা:

gawk --debug -f test.awk

ডিবাগার কনসোলে:

$ dgawk -f test.awk
dgawk> trace on
dgawk> watch a
Watchpoint 1: a
dgawk> run
Starting program: 
[     1:0x7fe59154cfe0] Op_rule             : [in_rule = BEGIN] [source_file = test.awk]
[     2:0x7fe59154bf80] Op_push_i           : 0 [PERM|NUMCUR|NUMBER]
[     2:0x7fe59154bf20] Op_store_var        : a [do_reference = FALSE]
[     3:0x7fe59154bf60] Op_push_lhs         : a [do_reference = TRUE]
Stopping in BEGIN ...
Watchpoint 1: a
  Old value: untyped variable
  New value: 0
main() at `test.awk':3
3           !a++;
dgawk> step
[     3:0x7fe59154bfc0] Op_postincrement    : 
[     3:0x7fe59154bf40] Op_not              : 
Watchpoint 1: a
  Old value: 0
  New value: 1
main() at `test.awk':3
3           !a++;
dgawk>

আপনি দেখতে পারেন, Op_postincrementআগে মৃত্যুদন্ড কার্যকর করা হয়েছিল Op_not

এছাড়াও আপনি ব্যবহার করতে পারেন siবা stepiপরিবর্তে sবা stepআরও স্পষ্টভাবে দেখতে:

dgawk> si
[     3:0x7ff061ac1fc0] Op_postincrement    : 
3           !a++;
dgawk> si
[     3:0x7ff061ac1f40] Op_not              : 
Watchpoint 1: a
  Old value: 0
  New value: 1
main() at `test.awk':3
3           !a++;

3
@ আরচেমার: আপনার উত্তরটি ইঙ্গিত করে যে !এটি আগে প্রয়োগ করা হয়েছিল ++
cuonglm

6
এই উত্তরটি ভুল। !অপারেটরের ফলাফল গণনা করার পরে বর্ধন ঘটে । মূল্যায়নের ক্রম সহ আপনি অপারেটর অগ্রাধিকারটি ( !a[$0]++যেমন পার্স করা হয় !(a[$0]++)) বিভ্রান্ত করছেন ( a[$0]এক্সপ্রেশনটির মান গণনার পরে নতুন মান নির্ধারিত হবে)।
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

5
@ জ্নোক এটি আপনার উদ্ধৃত প্যাসেজের ঠিক কথাই বলেছে, এবং এটি যদি আপনার বর্ণিত পদ্ধতিতে কাজ করে তবে এই কোডটি পছন্দসই প্রভাব ফেলবে না। প্রথম মান !xগণনা করা হয়, যেখানে xপুরোনো মান a[$0]। তারপরে a[$0]সেট করা আছে 1+x
গিলস 'অশুভ হওয়া বন্ধ করুন'

7
আমি বিশ্বাস করি যে অবাস্তব কী করে তা আপনার বিশ্লেষণ সঠিক। আমি যদি গতকাল অন্যথায় প্ররোচিত করি তবে দুঃখিত। যাইহোক, আরচেমারের উত্তর নিয়ে আপনার সমালোচনা ভুল। আরকেমার অগ্রাধিকারকে ভুল বোঝে না, আপনি করেন, আপনি মূল্যায়নের আদেশের সাথে বিভ্রান্তিকর প্রাধান্যটি (আমার আগের মন্তব্যটি দেখুন)। আপনি যদি নিজের মধ্যে আরচেরারের জবাবের কোনও উল্লেখ সরিয়ে ফেলেন তবে আপনার উত্তরটি সঠিক হওয়া উচিত। যেমনটি রয়েছে, এটি আর্কেমারকে ভুল প্রমাণ করার দিকে দৃষ্টি নিবদ্ধ করেছে, এবং এটি তেমন নয়।
গিলস 'অশুভ হওয়া বন্ধ করুন'

5
ভাল, কমপক্ষে এখন আমি
জড়িত
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.