Awk ব্যবহার করে ক্ষেত্রের একটি চলক সংখ্যার সাথে ফাইলের প্রথম কলামের প্রস্থ পরিবর্তন করুন


10

আমি কীভাবে awk এর প্রিন্টফ ফাংশনটি ব্যবহার করতে পারি তা বুঝতে পারি তবে আমি প্রতিটি ক্ষেত্র নির্দিষ্ট করতে চাই না।

উদাহরণস্বরূপ, ধরুন এটি আমার ফাইল:

c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15

আমি এটি ফর্ম্যাট করতে চাই যাতে প্রতিটি রেকর্ডের প্রথম ক্ষেত্রটি সি 11 এর প্রস্থ হয় - প্রথম ক্ষেত্রের দীর্ঘতম ঘর:

c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15

আমি বুঝতে পারি যে আমি নির্দিষ্ট করতে পারি:

awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile

আসুন ধরে নেওয়া যাক আমি জানি যে আমি প্রথম কলামটির প্রস্থ কী হতে চাই, তবে ফাইলটিতে কতগুলি ক্ষেত্র রয়েছে তা আমি জানি না। মূলত আমি এরকম কিছু করতে চাই:

... '{printf "%-3s|", $1}'

... এবং তারপরে বাকী ক্ষেত্রগুলি তাদের মূল ফর্ম্যাটে মুদ্রণ করুন।


এটিকে সম্বোধনের আরেকটি উপায়: sed 's/|/'' '' '' |/;s/\(...\) */\1/'(এসই মন্তব্যগুলি সংক্ষিপ্ত স্থানগুলিকে একের মধ্যে
মিশ্রণ

উত্তর:


14

আপনি কেবল sprintfপুনরায় ফর্ম্যাট করতে ব্যবহার করতে পারেন $1

যাত্রা।

$ awk 'BEGIN{OFS=FS="|"} {$1 = sprintf("%-3s",$1)} 1' file
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15

সংক্ষিপ্ত, আপনি awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
স্প্রিন্টফের

@ এ। ড্যানিশচেউস্কি - ভাল, ডাং আমি aw 17 বছর ধরে বিস্তীর্ণ অ্যাজক প্রোগ্রামিং করছি, এবং এর আগে কখনও আসেনি। সমস্ত ঝামেলা ভাবতে ভাবতে সে আমাকে বাঁচিয়ে দিত।
পল সিনক্লেয়ার

6

প্রথম ক্ষেত্রের বৃহত্তম / দীর্ঘতম দৈর্ঘ্য নির্ধারণ করতে এবং তারপরে ক্ষেত্রের মানগুলি দৈর্ঘ্য অনুসারে পুনরায় ফর্ম্যাট করতে আপনাকে ফাইলের ওপরে দুটি পৃথক পাস করতে হবে।

awk 'BEGIN     { OFS = FS = "|" }
     FNR == NR { if (m < (n=length($1))) m = n; next }
               { $1 = sprintf("%-*s", m, $1); print }' file file

(নোট করুন যে ইনপুট ফাইলটি কমান্ড লাইনে দু'বার নির্দিষ্ট করা আছে)

আপনার উপস্থাপন করা ডেটার জন্য, এটি উত্পাদন করবে

c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15

প্রথম পাসটি FNR == NRব্লক দ্বারা পরিচালিত হয় , যা এ পর্যন্ত দেখা দীর্ঘতম ক্ষেত্রটির সন্ধান করে ( mসর্বাধিক দেখা দৈর্ঘ্য ধারণ করে) এবং পরবর্তী লাইনে চলে যায়।

দ্বিতীয় পাসটি শেষ ব্লক দ্বারা পরিচালিত হয়, যা প্রথম ক্ষেত্রটি ব্যবহার করে পুনরায় ফর্ম্যাট করে sprintf()। বিন্যাসের স্ট্রিংয়ের %-*sঅর্থ "একটি বাম-ন্যায়সঙ্গত স্ট্রিং যার প্রস্থটি প্রকৃত স্ট্রিং ধারণ করে এমন আর্গুমেন্টের পূর্বে পূর্ণসংখ্যার আর্গুমেন্ট দ্বারা দেওয়া হয়"।

এটি অবশ্যই mপ্রতিটি কলামের সর্বাধিক প্রস্থকে ধারণ করে এমন একটি অ্যারেতে স্কেলারটিকে পরিণত করে সমস্ত কলামগুলি করার জন্য এটি স্পষ্টত বাড়ানো যেতে পারে :

$ awk 'BEGIN     { OFS = FS = "|" }
       FNR == NR { for (i=1; i<=NF; ++i) if (m[i] < (n=length($i))) m[i] = n; next }
                 { for (i=1; i<=NF; ++i) $i = sprintf("%-*s", m[i], $i); print }' file file
c1 |c2 |c3 |c4 |c5
c6 |c7 |c8 |c9 |c10
c11|c12|c13|c14|c15

1

বুদ্ধিমান উপায় হ'ল স্টিলড্রাইভার পরামর্শ দিয়েছিল । অহেতুকভাবে সংশ্লেষিত উপায় হ'ল প্রতিটি ক্ষেত্রের পুনরাবৃত্তি:

$ awk -F'|' '{printf "%-3s|",$1; for(i=2;i<NF;i++){printf "%s|",$i} printf "%s\n", $i}' file
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15

তবে ঠিক sprintf $1এবং এটি দিয়ে করা।


1
আপনি এটি সামান্য পিছনে পেয়েছেন, ছোট সংক্ষিপ্ত বিবৃতি সাধারণত আরও বিশৃঙ্খল হয়। ক্ষেত্রগুলির উপরে আইট্রেট করা কম সংশ্লেষিত হয় না।
ড্যানিশচেউস্কি

1

ওউকে আপনি ডায়নামিক প্রিন্টফ ফর্ম্যাট স্ট্রিং তৈরি করতে একটি "*" ব্যবহার করতে পারেন।

আপনি যদি ইতিমধ্যে দৈর্ঘ্যটি জানেন তবে আপনি প্রথম কলামের ক্ষেত্রের দৈর্ঘ্যটি -v দিয়ে পাস করতে পারেন।

awk -vcol1=3 'BEGIN{FS="|"}{for(i=1;i<=NF;i++){if(i==1)printf "%*-s%s",col1,$i,FS;else if(i!=NF)printf "%s%s",$i,FS;else printf "%s\n",$i;};}' test.txt

দ্রষ্টব্য: যদি আপনি না জানতেন যে প্রথম কলামের দৈর্ঘ্যটি কোন অ্যারেতে মানগুলি সংরক্ষণ করতে পারে তবে সর্বাধিক কর্নের দৈর্ঘ্যটি সন্ধান করতে হবে এবং এটিকে এন্ড ব্লকের মধ্যে মুদ্রণ করতে হবে।

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