নবম থেকে শেষ অবধি সমস্ত কলাম মুদ্রণ করতে awk ব্যবহার করে


309

আমার দ্বিতীয় ক্ষেত্রের শ্বেতক্ষেত্র না হওয়া পর্যন্ত এই লাইনটি কাজ করেছিল।

svn status | grep '\!' | gawk '{print $2;}' > removedProjs

k 2 বা তার চেয়েও বেশি কিছুতে কী সবুজ মুদ্রণের উপায় আছে? ($ 3, $ 4 .. যতক্ষণ না আমাদের আর কলাম না থাকে?)

আমি মনে করি আমার যুক্ত করা উচিত যে আমি সাইগউইনের সাথে উইন্ডোজ পরিবেশে এটি করছি।


11
অন্যদিকে, grep | awkএটি একটি প্রতিরোধ ব্যবস্থা - আপনি চানawk '/!/ { print $2 }'
ট্রিপল করুন

3
ইউনিক্স "কাটা" সহজ ...svn status | grep '\!' | cut -d' ' -f2- > removedProjs
রোব্লগিক


@ ট্রিপলি: আমি খুব খুশি যে আপনি এটি উল্লেখ করেছেন - আমি সর্বত্র এটি দেখে হতাশ!
গ্রাহাম নিকোলস

উত্তর:


489

প্রথম কলামটি ছাড়াও সমস্ত মুদ্রণ করবে:

awk '{$1=""; print $0}' somefile

দুটি প্রথম কলাম বাদে সমস্ত মুদ্রণ করবে:

awk '{$1=$2=""; print $0}' somefile

93
গ্যাচা: একটি অগ্রণী স্থান সম্পর্কে ঝাঁকুনি
ছাড়বে

5
আমি ব্যবহারিক পদ্ধতির পছন্দ করি। যদিও বিড়াল ব্যবহার করার দরকার নেই, কেবল ফাইল নাম রাখা উচিত আদেশ কমান্ডের পরে।
কান

45
@raphinesse আপনি এটি দিয়ে ঠিক করতে পারেনawk '{$1=""; print substr($0,2)}' input_filename > output_filename
themiurgo

6
এটি অ-হোয়াইটস্পেস ডিলিমিটারের সাথে কাজ করে না, তাদের স্থানের সাথে প্রতিস্থাপন করে।
দেজন

3
অ-হোয়াইটস্পেস ডিলিমিটারগুলির জন্য, আপনি আউটপুট ফিল্ড বিভাজক (ওএফএস) নির্দিষ্ট করতে পারেন, যেমন কমাতে: awk -F, -vOFS=, '{$1=""; print $0}'আপনি একটি প্রাথমিক ডিলিমিটার দিয়ে শেষ করবেন ( $1এখনও খালি স্ট্রিং হিসাবে অন্তর্ভুক্ত রয়েছে)। আপনি sedযদিও এটি awk -F, -vOFS=, '{$1=""; print $0}' | sed 's/^,//'
ছাঁটাই

99

কাটা ব্যবহার করে একটি সহজ উত্তর সহ একটি সদৃশ প্রশ্ন আছে :

 svn status |  grep '\!' | cut -d\  -f2-

-dনির্দিষ্ট করে delimeter (স্থান) , -fকলামের তালিকা নির্দিষ্ট করে (সব 2nd দিয়ে শুরু)


আপনি অবস্থানটি নির্দিষ্ট করতে "-b" ব্যবহার করতে পারেন (Nth অক্ষর থেকে পরবর্তী)।
ডাকাটাইন

একটি নোট হিসাবে, যদিও এই সঞ্চালিত একই টাস্ক হিসাবে awkসংস্করণ, সেখানে সঙ্গে সঙ্গতিপূর্ণ বাফারিং বিষয় আছে cut, যা awk: নেই stackoverflow.com/questions/14360640/...
sdaau

24
দুর্দান্ত এবং সহজ, তবে একটি সতর্কতার সাথে আসে: awkএকাধিক সংলগ্ন স্থানের অক্ষরের সাথে আচরণ করে। একক বিভাজক হিসাবে , যদিও cutনা; এছাড়াও - যদিও এটি হাতের ক্ষেত্রে কোনও সমস্যা নয় - cutকেবল একটি একক, আক্ষরিক চর গ্রহণ করে। ডিলিমিটার হিসাবে, যেখানে awkএকটি রেজেসকে অনুমতি দেয়।
mklement0

এর ভিত্তিতে: স্ট্যাকওভারফ্লো.com / a / 39217130 / 8852408 , সম্ভবত এই সমাধানটি খুব কার্যকর নয় বলে সম্ভাব্য।
FcknGioconda

85

আপনি মুদ্রণ ক্ষেত্রগুলি $ 2 মাধ্যমে $ এনএফের মাধ্যমে লুপ করতে একটি লুপ ব্যবহার করতে পারেন (বিল্ট-ইন ভেরিয়েবল যা লাইনে ক্ষেত্রের সংখ্যা উপস্থাপন করে)।

সম্পাদনা: যেহেতু "মুদ্রণ" একটি নতুন লাইন যুক্ত হয়েছে, আপনি ফলাফলগুলি বাফার করতে চাইবেন:

awk '{out=""; for(i=2;i<=NF;i++){out=out" "$i}; print out}'

বিকল্পভাবে, প্রিন্টফ ব্যবহার করুন:

awk '{for(i=2;i<=NF;i++){printf "%s ", $i}; printf "\n"}'

সুতরাং আমি এটি চেষ্টা করেছিলাম, তবে মনে হয় আমি কিছু মিস করছি .. আমি এখানে এসএনএন স্ট্যাটাসটি করেছি গ্রেপ '\!' | gawk '{for (i = 1; i <= $ NF; i ++) মুদ্রণ করুন $ i "";}'> সরানোপ্রজ
অ্যান্ডি

যেহেতু মুদ্রণ একটি নতুন লাইন যুক্ত হয়েছে, আপনি ফলাফলগুলি বাফার করতে চাইবেন। আমার সম্পাদনা দেখুন।
VeeArr

1
আমি এই উত্তরটি আরও ভাল পছন্দ করি কারণ এটি ক্ষেত্রগুলি দিয়ে কীভাবে লুপ করবেন তা দেখায়।
এডওয়ার্ড ফ্যাল্ক

3
যদি আপনি মুদ্রণ কোনও স্থান ব্যবহার করতে চান তবে আউটপুট রেকর্ড বিভাজকটি পরিবর্তন করুন: awk '{ORS = ""; (i = 2; i <NF; i ++) মুদ্রণ করুন $ i} '
সামিফাইল

3
সর্বদা কিছু জায়গা খুব বেশি থাকবে। এটি আরও ভাল কাজ করে: '{for(i=11;i<=NF-1;i++){printf "%s ", $i}; print $NF;}'কোনও নেতৃস্থানীয় বা পিছনে স্থান নেই।
মার্কি

24
awk '{out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}'

আমার উত্তরটি ভিআরারের একটিতে ভিত্তিক , তবে আমি লক্ষ্য করেছি যে এটি দ্বিতীয় কলামটি প্রিন্ট করার আগেই এটি একটি সাদা জায়গা দিয়ে শুরু হয়েছিল (এবং বাকীটি )। যেহেতু আমার কাছে কেবল 1 খ্যাতি রয়েছে, আমি এটি সম্পর্কে মন্তব্য করতে পারি না, সুতরাং এটি এখানে একটি নতুন উত্তর হিসাবে যায়:

দ্বিতীয় কলাম হিসাবে "আউট" দিয়ে শুরু করুন এবং তারপরে অন্যান্য সমস্ত কলাম যুক্ত করুন (যদি সেগুলি বিদ্যমান থাকে)। এটি যতক্ষণ না দ্বিতীয় কলাম থাকবে ততক্ষণ চলে।


2
দুর্দান্ত, আপনি আউট ভেরিয়েবলের সামনেও মুছে ফেললেন যা খুব গুরুত্বপূর্ণ।
অ্যালেক্সিস উইল্ক

15

বেশিরভাগ সমাধান সহ বেশিরভাগ সমাধান একটি স্থান ছেড়ে যায়। এখানে বিকল্পগুলি এই সমস্যাটি এড়ায়।

বিকল্প 1

একটি সাধারণ কাটা সমাধান (শুধুমাত্র একক ডিলিমিটারগুলির সাথে কাজ করে):

command | cut -d' ' -f3-

বিকল্প 2

কখনও কখনও পুনরায় ক্যালক জোর করে প্রথম ক্ষেত্রগুলি বাদ দিয়ে অ্যাডেড লিডিং স্পেস (ওএফএস) সরিয়ে ফেলুন (কিছু সংস্করণের সাথে কাজ করে):

command | awk '{ $1=$2="";$0=$0;} NF=NF'

বিকল্প 3

প্রতিটি ক্ষেত্রের সাথে ফর্ম্যাট করা মুদ্রণ printfআরও নিয়ন্ত্রণ দেবে:

$ in='    1    2  3     4   5   6 7     8  '
$ echo "$in"|awk -v n=2 '{ for(i=n+1;i<=NF;i++) printf("%s%s",$i,i==NF?RS:OFS);}'
3 4 5 6 7 8

যাইহোক, পূর্ববর্তী সমস্ত উত্তরগুলি ক্ষেত্রগুলির মধ্যে সমস্ত পুনরাবৃত্তি FS কে OFS এ পরিবর্তন করে। আসুন এমন একটি দম্পতি তৈরি করুন যা এটি না করে।

বিকল্প 4 (প্রস্তাবিত)

সামনের ক্ষেত্রগুলি এবং ডিলিমিটারগুলি সরাতে সাব সহ একটি লুপ।
এবং জায়গার পরিবর্তে এফএসের মান ব্যবহার করে (যা পরিবর্তিত হতে পারে)।
আরও পোর্টেবল, এবং এফএস-এর পরিবর্তনগুলিকে অফস-এ পরিবর্তিত করে না: দ্রষ্টব্য:^[FS]* শীর্ষস্থানীয় স্পেসগুলির সাথে একটি ইনপুট গ্রহণ করা The

$ in='    1    2  3     4   5   6 7     8  '
$ echo "$in" | awk '{ n=2; a="^["FS"]*[^"FS"]+["FS"]+";
  for(i=1;i<=n;i++) sub( a , "" , $0 ) } 1 '
3     4   5   6 7     8

বিকল্প 5

এমন একটি সমাধান তৈরি করা সম্ভব যা অতিরিক্ত (শীর্ষস্থানীয় বা পিছনে) সাদা স্থান যোগ করে না এবং gensubজিএনইউ অ্যাডক থেকে ফাংশনটি ব্যবহার করে বিদ্যমান হোয়াইটস্পেস সংরক্ষণ করে :

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          { print(gensub(a""b""c,"",1)); }'
3     4   5   6 7     8 

এটি একটি গণনা প্রদত্ত ক্ষেত্রগুলির একটি গ্রুপকে অদলবদল করতেও ব্যবহৃত হতে পারে n:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          {
            d=gensub(a""b""c,"",1);
            e=gensub("^(.*)"d,"\\1",1,$0);
            print("|"d"|","!"e"!");
          }'
|3     4   5   6 7     8  | !    1    2  !

অবশ্যই, এই ক্ষেত্রে, অফসটি লাইনের উভয় অংশ পৃথক করতে ব্যবহৃত হয়, এবং ক্ষেত্রগুলির পিছনে সাদা স্থানটি এখনও মুদ্রিত হয়।

দ্রষ্টব্য: [FS]* ইনপুট লাইনে শীর্ষস্থানীয় স্থানগুলিতে অনুমতি দেওয়ার জন্য ব্যবহৃত হয়।


13

আমি ব্যক্তিগতভাবে উপরে উল্লিখিত সমস্ত উত্তর চেষ্টা করেছিলাম, তবে তাদের বেশিরভাগই কিছুটা জটিল বা ঠিক নয়। আমার দৃষ্টিকোণ থেকে এটি করার সহজতম উপায় হ'ল:

awk -F" " '{ for (i=4; i<=NF; i++) print $i }'
  1. যেখানে -F "" ব্যবহারের জন্য ডাব্লিমিটারের জন্য সীমানা নির্ধারণ করে। আমার ক্ষেত্রে হোয়াইটস্পেস, এটি অ্যাজকের জন্য ডিফল্ট ডিলিমিটারও। এর অর্থ হ'ল -F "" এড়ানো যায়।

  2. যেখানে এনএফ মোট ক্ষেত্র / কলামগুলির সংখ্যা নির্ধারণ করে। অতএব লুপটি 4 র্থ ক্ষেত্র থেকে শেষ ক্ষেত্র / কলাম পর্যন্ত শুরু হবে।

  3. যেখানে $ N এনথ ক্ষেত্রের মান পুনরুদ্ধার করে। সুতরাং মুদ্রণ। আমি লুপ গণনার উপর ভিত্তি করে বর্তমান ক্ষেত্র / কলাম প্রিন্ট করব।


4
সমস্যা, যা প্রতিটি ক্ষেত্রকে আলাদা লাইনে মুদ্রণ করে।
mveroone

কিছুই আপনাকে শেষে এড করা বন্ধ করে না :-)। | tr '\ n' '' `
কাউলিস্প্প

3
কিছুটা দেরি হলেও অবাক '{' এর জন্য (i = 5; i <= NF; i++) {
প্রিন্টফ


7

এটি আমাকে এতটা বিরক্ত করেছিল, আমি বসে বসে একটি cutমত ফিল্ড স্পেসিফিকেশন পার্সার লিখেছি , এটি জিএনইউ অ্যাওক ৩.১..7 এর সাথে পরীক্ষিত।

প্রথমে pfcutউদাহরণস্বরূপ একটি নতুন Awk লাইব্রেরি স্ক্রিপ্ট তৈরি করুন

sudo nano /usr/share/awk/pfcut

তারপরে, নীচের স্ক্রিপ্টে আটকান এবং সংরক্ষণ করুন। এর পরে, ব্যবহারটি এরকম দেখাচ্ছে:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-4"); }'
t1 t2 t3 t4

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("2-"); }'
t2 t3 t4 t5 t6 t7

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

এই সমস্ত টাইপ করা এড়াতে, আমার ধারণা সর্বোত্তম যেটি করতে পারে (অন্যথায় অ্যাডাব্লু দিয়ে স্টার্টআপে কোনও ব্যবহারকারী ফাংশন স্বয়ংক্রিয়ভাবে লোড করুন? - ইউনিক্স এবং লিনাক্স স্ট্যাক এক্সচেঞ্জ ) এর সাথে একটি নাম যুক্ত হবে ~/.bashrc; যেমন:

$ echo "alias awk-pfcut='awk -f pfcut --source'" >> ~/.bashrc
$ source ~/.bashrc     # refresh bash aliases

... তাহলে আপনি কেবল কল করতে পারেন:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk-pfcut '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

এখানে pfcutলিপির উত্স :

# pfcut - print fields like cut
#
# sdaau, GNU GPL
# Nov, 2013

function spfcut(formatstring)
{
  # parse format string
  numsplitscomma = split(formatstring, fsa, ",");
  numspecparts = 0;
  split("", parts); # clear/initialize array (for e.g. `tail` piping into `awk`)
  for(i=1;i<=numsplitscomma;i++) {
    commapart=fsa[i];
    numsplitsminus = split(fsa[i], cpa, "-");
    # assume here a range is always just two parts: "a-b"
    # also assume user has already sorted the ranges
    #print numsplitsminus, cpa[1], cpa[2]; # debug
    if(numsplitsminus==2) {
     if ((cpa[1]) == "") cpa[1] = 1;
     if ((cpa[2]) == "") cpa[2] = NF;
     for(j=cpa[1];j<=cpa[2];j++) {
       parts[numspecparts++] = j;
     }
    } else parts[numspecparts++] = commapart;
  }
  n=asort(parts); outs="";
  for(i=1;i<=n;i++) {
    outs = outs sprintf("%s%s", $parts[i], (i==n)?"":OFS); 
    #print(i, parts[i]); # debug
  }
  return outs;
}

function pfcut(formatstring) {
  print spfcut(formatstring);
}

মনে হয় আপনি ব্যবহার করতে চান cut, নাawk
roblogic

5

# 2 থেকে শুরু হওয়া কলামগুলি মুদ্রণ করা (আউটপুটটির শুরুতে কোনও পিছনের স্থান থাকবে না):

ls -l | awk '{sub(/[^ ]+ /, ""); print $0}'

1
দুর্দান্ত, যদিও আপনার +জায়গার পরে যোগ করা উচিত , যেহেতু ক্ষেত্রগুলি 1 টিরও বেশি স্পেস দ্বারা পৃথক করা যেতে পারে ( awkএকাধিক সংলগ্ন স্পেসকে একক বিভাজক হিসাবে বিবেচনা করে)। এছাড়াও, awkশীর্ষস্থানীয় স্থানগুলিকে উপেক্ষা করবে, সুতরাং আপনার সাথে রেজিেক্স শুরু করা উচিত ^[ ]*। বিভাজক হিসাবে স্থানের সাথে আপনি এমনকি সমাধানটিকে সাধারণীকরণ করতে পারেন; উদাহরণস্বরূপ, নিম্নলিখিতটি তৃতীয় ক্ষেত্রের সমস্ত কিছু ফেরত দেয়: awk '{sub(/^[ ]*([^ ]+ +){2}/, ""); print $0}'যদিও এটি স্বেচ্ছাসেবী ক্ষেত্র বিভাজকগুলির সাথে কৌশলযুক্ত হয়।
mklement0

5

এই কাজ করবে?

awk '{print substr($0,length($1)+1);}' < file

এটি সামনে কিছু সাদা জায়গা ছেড়ে দেয় যদিও।


4
echo "1 2 3 4 5 6" | awk '{ $NF = ""; print $0}'

এটি সর্বশেষ ক্ষেত্রটি বাদে সমস্ত মুদ্রণ করতে বিশ্রী ব্যবহার করে


3

আমি সমস্ত প্রস্তাবনা থেকে এটি পছন্দ করেছি:

6th ষ্ঠ থেকে শেষ কলামে মুদ্রণ করা হচ্ছে।

ls -lthr | awk '{out=$6; for(i=7;i<=NF;i++){out=out" "$i}; print out}'

অথবা

ls -lthr | awk '{ORS=" "; for(i=6;i<=NF;i++) print $i;print "\n"}'

2

আপনার যদি স্বেচ্ছাসেবক ডিলিমিটার দিয়ে মুদ্রিত নির্দিষ্ট কলামগুলির প্রয়োজন হয়:

awk '{print $3 "  " $4}'

কল # 3 কল # 4

awk '{print $3 "anything" $4}'

কর্নেল # 3anythingcol # 4

সুতরাং আপনার যদি একটি কলামে শ্বেত স্পেস থাকে তবে এটি দুটি কলাম হবে তবে আপনি এটি কোনও ডিলিমিটারের সাথে বা এটি ছাড়া সংযোগ করতে পারেন।


2

পার্ল সমাধান:

perl -lane 'splice @F,0,1; print join " ",@F' file

এই কমান্ড-লাইন বিকল্পগুলি ব্যবহার করা হয়:

  • -n ইনপুট ফাইলের প্রতিটি লাইন প্রায় লুপ, প্রতিটি লাইন স্বয়ংক্রিয়ভাবে মুদ্রণ করবেন না

  • -l প্রসেসিংয়ের আগে নতুন লাইনগুলি সরিয়ে দেয় এবং পরে এগুলিতে আবার যুক্ত করে

  • -aঅটোস্প্লিট মোড - @F অ্যারেতে বিভক্ত ইনপুট লাইনগুলি। সাদা স্থানটিতে বিভাজনে ডিফল্ট

  • -e পার্ল কোডটি কার্যকর করুন

splice @F,0,1 পরিষ্কারভাবে @F অ্যারে থেকে 0 কলামটি সরিয়ে দেয়

join " ",@F প্রতিটি উপাদানগুলির মধ্যে একটি স্পেস ব্যবহার করে @F অ্যারের উপাদানগুলিতে যোগদান করে


পাইথন দ্রবণ:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[1:]) + '\n') for line in sys.stdin]" < file


1

আপনি যদি লাইনটি কাটেন না এমন অংশটির পুনরায় ফর্ম্যাট করতে না চান তবে আমি যে উত্তম সমাধানটি ভাবতে পারি তা আমার উত্তরে লিখিত আছে:

অ্যাজকি ব্যবহার করে কোনও নির্দিষ্ট সংখ্যার পরে সমস্ত কলাম কীভাবে মুদ্রণ করবেন?

এটি প্রদত্ত ক্ষেত্র নম্বর এন এর আগে যা রয়েছে তা হ্রাস করে এবং ক্ষেত্রের নম্বর এন সহ এবং অন্যান্য মূল রেখা মুদ্রণ করে মূল স্পেসিং বজায় রাখে (এটি পুনরায় ফর্ম্যাট করে না)। যদি ক্ষেত্রের স্ট্রিংটি লাইনের অন্য কোথাও প্রদর্শিত হয় তবে এটি ম্যাটার করে না।

একটি ফাংশন সংজ্ঞায়িত করুন:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

এবং এটি এর মতো ব্যবহার করুন:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost 

আউটপুট পিছনে স্থান সহ সমস্ত কিছু বজায় রাখে

আপনার বিশেষ ক্ষেত্রে:

svn status | grep '\!' | fromField 2 > removedProjs

যদি আপনার ফাইল / স্ট্রিমে রেখার মাঝে নতুন রেখার অক্ষর না থাকে (আপনি কোনও ভিন্ন রেকর্ড বিভাজক ব্যবহার করতে পারেন) তবে আপনি ব্যবহার করতে পারেন:

awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

প্রথম কেসটি কেবল সেই ফাইল / স্ট্রিমগুলিতে ব্যর্থ হবে যা বিরল হেক্সাডেসিমাল চর নম্বর 1 রয়েছে


0

এটি কাজ করবে যদি আপনি বাশ ব্যবহার করছেন এবং আপনি যে উপাদানগুলিকে বাতিল করতে চান হিসাবে আপনি অনেকগুলি 'এক্স' ব্যবহার করতে পারেন এবং যদি তারা পালাতে না পারেন তবে এটি একাধিক স্পেস উপেক্ষা করে।

while read x b; do echo "$b"; done < filename

0

পার্ল:

@m=`ls -ltr dir | grep ^d | awk '{print \$6,\$7,\$8,\$9}'`;
foreach $i (@m)
{
        print "$i\n";

}

1
এটি প্রশ্নের উত্তর দেয় না, যা Nth কলাম থেকে শেষ পর্যন্ত মুদ্রণের প্রয়োজনকে সাধারণ করে তোলে ।
রোয়াইমা

0

এই awkফাংশন আয় সাবস্ট্রিং $0থেকে ক্ষেত্রগুলি অন্তর্ভুক্ত beginকরার end:

function fields(begin, end,    b, e, p, i) {
    b = 0; e = 0; p = 0;
    for (i = 1; i <= NF; ++i) {
        if (begin == i) { b = p; }
        p += length($i);
        e = p;
        if (end == i) { break; }
        p += length(FS);
    }
    return substr($0, b + 1, e - b);
}

ক্ষেত্র 3 থেকে শুরু করে সমস্ত কিছু পেতে:

tail = fields(3);

$0ক্ষেত্রগুলির 3 থেকে 5 টি পর্যন্ত বিভাগটি পেতে :

middle = fields(3, 5);

b, e, p, iফাংশন প্যারামিটার তালিকার awkবোকামি স্থানীয় ভেরিয়েবলগুলি ঘোষণার একমাত্র উপায়।


0

আমি সম্ভবত বেশ কয়েকটি শ্বেত স্পেসের মাধ্যমে ক্ষেত্রগুলি সীমিত করে রেখেছি এমন পরিস্থিতিতে প্রস্তাবিত উত্তরগুলি প্রসারিত করতে চাই - কেন ওপি ব্যবহার করছে নাcut আমি মনে করি যে ।

আমি জানি ওপি সম্পর্কে জিজ্ঞাসা করা হয়েছিল awk, তবে একটি sedপদ্ধতি এখানে কাজ করবে (উদাহরণস্বরূপ 5 ম থেকে শেষ পর্যন্ত কলাম মুদ্রণ সহ):

  • খাঁটি সেড পদ্ধতির

    sed -r 's/^\s*(\S+\s+){4}//' somefile

    ব্যাখ্যা:

    • s/// প্রতিস্থাপন সম্পাদনের জন্য স্ট্যান্ডার্ড পদ্ধতিতে ব্যবহৃত হয়
    • ^\s* লাইনের শুরুতে পর পরের যে কোনও সাদা স্থানের সাথে মেলে
    • \S+\s+ অর্থের একটি কলাম (সাদা অংশের অক্ষর অনুসারে শ্বেতস্থান অক্ষর) বোঝায়
    • (){4} মানে প্যাটার্নটি 4 বার পুনরাবৃত্তি হয়েছে।
  • সেড এবং কাটা

    sed -r 's/^\s+//; s/\s+/\t/g' somefile | cut -f5-

    কেবলমাত্র একক ট্যাব দ্বারা পরপর শ্বেত স্থান পরিবর্তন করে;

  • টিআর এবং কাট: অপশনটি দিয়ে ক্রমাগত অক্ষরগুলিও ছড়িয়েtr দিতে ব্যবহার করা যেতে পারে ।-s

    tr -s [:blank:] <somefile | cut -d' ' -f5-

-1

অজগর উদাহরণগুলি এখানে জটিল দেখায়, এখানে সরল বাশ শেল সিনট্যাক্স রয়েছে:

command | while read -a cols; do echo ${cols[@]:1}; done

0 থেকে 1আপনার n তম কলামের গণনা কোথায় ?


উদাহরণ

ফাইলের এই বিষয়বস্তু দেওয়া ( in.txt):

c1
c1 c2
c1 c2 c3
c1 c2 c3 c4
c1 c2 c3 c4 c5

এখানে ফলাফল:

$ while read -a cols; do echo ${cols[@]:1}; done < in.txt 

c2
c2 c3
c2 c3 c4
c2 c3 c4 c5

-1

আমি awkএখানে উপস্থাপিত যে কোনও সমাধান নিয়ে খুশি ছিলাম না কারণ আমি প্রথম কয়েকটি কলামটি বের করতে এবং তারপরে বাকীগুলি মুদ্রণ করতে চেয়েছিলাম, সুতরাং আমি perlপরিবর্তে ফিরেছি । নিম্নলিখিত কোডটি প্রথম দুটি কলাম আহরণ করে এবং বাকিটি যেমন প্রদর্শিত করে:

echo -e "a  b  c  d\te\t\tf g" | \
  perl -ne 'my @f = split /\s+/, $_, 3; printf "first: %s second: %s rest: %s", @f;'

ক্রিস কোকনাটperl থেকে সমাধানের তুলনায় সুবিধা সত্য যে কেবল প্রথম এন উপাদানগুলি ইনপুট স্ট্রিং থেকে বিভক্ত হয়; বাকি স্ট্রিং মোটেও বিভক্ত হয় নি এবং এর জন্য সম্পূর্ণ অক্ষত থাকে। আমার উদাহরণটি ফাঁকা স্থান এবং ট্যাবগুলির মিশ্রণ দ্বারা এটি প্রকাশ করে।

যে কলামগুলি বের করা উচিত তার পরিমাণ পরিবর্তন করতে, 3উদাহরণটিতে এন + 1 দিয়ে প্রতিস্থাপন করুন ।


-1
ls -la | awk '{o=$1" "$3; for (i=5; i<=NF; i++) o=o" "$i; print o }'

এই উত্তরটি থেকে খারাপ নয় তবে প্রাকৃতিক ব্যবধান চলে গেছে।
দয়া করে এটির সাথে এটির তুলনা করুন:

ls -la | cut -d\  -f4-

তারপরে আপনি পার্থক্যটি দেখতে পাবেন।

এমনকি ls -la | awk '{$1=$2=""; print}'যা উত্তরের উপর ভিত্তি করে তৈরি করা হয়েছে এখনও এ পর্যন্ত ফর্ম্যাটটি সংরক্ষণ করে না।

সুতরাং আমি নিম্নলিখিতটি ব্যবহার করব এবং এটি শুরুতে সুস্পষ্ট নির্বাচনী কলামগুলিকেও অনুমতি দেয়:

ls -la | cut -d\  -f1,4-

নোট করুন যে প্রতিটি স্থান কলামের জন্যও গণনা করে, তাই উদাহরণস্বরূপ নীচের অংশে 1 এবং 3 কলাম ফাঁকা, 2 টি INFO এবং 4 হ'ল:

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f1,3

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f2,4
INFO 2014-10-11
$

-1

যদি আপনি ফর্ম্যাট পাঠ্য চান, আপনার কমান্ডগুলি প্রতিধ্বনি দিয়ে চেইন করুন এবং শেষ ক্ষেত্রটি প্রিন্ট করতে $ 0 ব্যবহার করুন।

উদাহরণ:

for i in {8..11}; do
   s1="$i"
   s2="str$i"
   s3="str with spaces $i"
   echo -n "$s1 $s2" | awk '{printf "|%3d|%6s",$1,$2}'
   echo -en "$s3" | awk '{printf "|%-19s|\n", $0}'
done

ছাপে:

|  8|  str8|str with spaces 8  |
|  9|  str9|str with spaces 9  |
| 10| str10|str with spaces 10 |
| 11| str11|str with spaces 11 |

-9

340 ভোট নিয়ে একটি ভুল সর্বাধিক উত্সাহিত অ্যা্যান্সারের কারণে, আমি আমার জীবনের 5 মিনিট হারিয়েছি! কেউ উত্তর দেওয়ার আগে কি এই উত্তরটি চেষ্টা করে দেখেছিল? সুস্পষ্টভাবে না। সম্পূর্ণ অকেজো।

আমার একটি লগ রয়েছে যেখানে আইপি ঠিকানা সহ an 5 এর পরে আরও পাঠ্য বা কোনও পাঠ্য হতে পারে। আইপি ঠিকানা থেকে শুরু করে লাইনের শেষ পর্যন্ত আমার সবকিছু দরকার $ 5 এর পরে কিছু থাকা উচিত। আমার ক্ষেত্রে, এটি বাস্তবতই একটি অ্যাডাব্লিক প্রোগ্রাম সহ, কোনও অ্যাজক অনেলাইনার নয়, তাই এইডকে অবশ্যই সমস্যার সমাধান করতে হবে। যখন আমি সর্বাধিক উত্সাহিত কিন্তু সম্পূর্ণ ভুল উত্তরটি ব্যবহার করে প্রথম 4 টি ক্ষেত্র সরিয়ে দেওয়ার চেষ্টা করি:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'

এটি ভুল এবং অকেজো সাড়া ফেলে দিয়েছে (আমি প্রদর্শন করতে [..] যোগ করেছি):

[    37.244.182.218 one two three]

এমনকি এই ভুল উত্তরের সাথে সাবস্ট্রিটার একত্রিত করার জন্য কিছু সংক্ষেপণ রয়েছে। যে জটিলতা একটি উন্নতি হয়।

পরিবর্তে, যদি কাট পয়েন্ট এবং অ্যাজক প্রয়োজন না হওয়া অবধি কলামগুলি নির্দিষ্ট প্রস্থ হয়ে থাকে, সঠিক উত্তরটি হ'ল:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{printf "[%s]\n", substr($0,28)}'

যা কাঙ্ক্ষিত আউটপুট উত্পাদন করে:

[37.244.182.218 one two three]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.