একটি লাইনে কতক্ষণ ট্যাব '\ t' রয়েছে তা নির্ধারণ করুন


10

কোনও পাঠ্য প্রক্রিয়াকরণ ক্ষেত্রে কোনও ট্যাবটি 8 অক্ষরের দৈর্ঘ্য (ডিফল্ট দৈর্ঘ্য) বা তার চেয়ে কম কিনা তা জানার কোনও উপায় আছে?

উদাহরণস্বরূপ, যদি আমার কাছে ট্যাব ডিলিমিটার সহ একটি নমুনা ফাইল থাকে এবং একটি ক্ষেত্রের সামগ্রীতে একটিরও কম ট্যাব (≤7) ফিট থাকে এবং তার পরে আমার যদি একটি ট্যাব থাকে, তবে সেই ট্যাবটি কেবল 'ট্যাব আকার - ক্ষেত্রের আকার হবে ' দৈর্ঘ্যে.

কোনও লাইনে ট্যাবগুলির মোট দৈর্ঘ্য পাওয়ার কোনও উপায় আছে কি? আমি ট্যাবগুলির সংখ্যা খুঁজছি না (অর্থাত 10 টি ট্যাবগুলি 10 ফেরত দেওয়া উচিত নয়) তবে সেই ট্যাবগুলির চরিত্রের দৈর্ঘ্য।

নিম্নলিখিত ইনপুট ডেটার জন্য (ক্ষেত্র এবং কেবলমাত্র একটি ট্যাবের মধ্যে সীমাবদ্ধ ট্যাব):

field0  field00 field000        last-field
fld1    fld11   fld001  last-fld
fd2     fld3    last-fld

আমি প্রতিটি লাইনে ট্যাবগুলির দৈর্ঘ্য গণনা করার প্রত্যাশা করি, তাই

11
9
9

উত্তর:


22

TABচরিত্র একটি নিয়ন্ত্রণ চরিত্র যা একটি terminal¹ পাঠানো পরবর্তী ট্যাব স্টপ টার্মিনাল এর কার্সার সরানোর করে তোলে। ডিফল্টরূপে, বেশিরভাগ টার্মিনালগুলিতে, ট্যাব স্টপগুলি 8 টি কলাম পৃথক পৃথক, তবে এটি কনফিগারযোগ্য।

অনিয়মিত বিরতিতে আপনি ট্যাব স্টপগুলিও রাখতে পারেন:

$ tabs 3 9 11; printf '\tx\ty\tz\n'
  x     y z

কেবলমাত্র টার্মিনালই জানে যে কোনও টিএবি ডানদিকে কতগুলি কলামটি কার্সারটি সরবে।

ট্যাব প্রেরণের আগে এবং পরে টার্মিনাল থেকে কার্সারের অবস্থানটি জিজ্ঞাসা করে আপনি এই তথ্যটি পেতে পারেন।

আপনি যদি কোনও প্রদত্ত লাইনের জন্য হাতে গণনা করতে চান এবং ধরে নিচ্ছেন যে পংক্তিটি স্ক্রিনের প্রথম কলামে মুদ্রিত হয়েছে, আপনার প্রয়োজন হবে:

  • ট্যাব স্টপগুলি কোথায় তা জেনে নিন ²
  • জানি যে চরিত্রের প্রদর্শন প্রস্থ
  • পর্দার প্রস্থ জানুন
  • আপনি অন্যান্য নিয়ন্ত্রণের অক্ষরগুলি হ্যান্ডেল করতে চান কিনা তা স্থির করুন \r(যা কার্সারটিকে প্রথম কলামে নিয়ে যায়) বা \bএটি কার্সারটিকে পিছনে নিয়ে যায় ...)

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

জিএনইউ সহ wc, যদি লাইনটি এতে সঞ্চয় থাকে $line:

width=$(printf %s "$line" | wc -L)
width_without_tabs=$(printf %s "$line" | tr -d '\t' | wc -L)
width_of_tabs=$((width - width_without_tabs))

wc -Lএর ইনপুটটিতে প্রশস্ত রেখার প্রস্থ দেয়। এটি wcwidth(3)অক্ষরের প্রস্থ নির্ধারণ করতে এবং ট্যাব স্টপগুলি প্রতি 8 টি কলামে ধরে রেখে তা ব্যবহার করে।

নন-জিএনইউ সিস্টেমগুলির জন্য এবং একই অনুমান সহ, @ কুসালানন্দের পদ্ধতির দেখুন । এটি আরও ভাল হিসাবে এটি আপনাকে ট্যাব স্টপগুলি নির্দিষ্ট করতে দেয় তবে দুর্ভাগ্যক্রমে বর্তমানে জিএনইউ expand(কমপক্ষে) সাথে কাজ করে না যখন ইনপুটটিতে বহু-বাইট অক্ষর বা 0-প্রস্থ (অক্ষরের সংমিশ্রণের মতো) বা ডাবল-প্রস্থের অক্ষর রয়েছে।


¹ মনে রাখবেন যে আপনি যদি এটি করেন তবে stty tab3tty ডিভাইস লাইন শৃঙ্খলা ট্যাব প্রসেসিংয়ের দায়িত্ব নেবে (টার্মিনালে প্রেরণের আগে কার্সারটি কোথায় থাকতে পারে তার নিজস্ব ধারণার ভিত্তিতে টিএবি স্থানগুলিতে রূপান্তরিত করবে) এবং ট্যাব প্রয়োগ করে প্রতি 8 টি কলাম থামিয়ে দেয়। লিনাক্সে পরীক্ষা করে দেখে মনে হচ্ছে এটি সঠিকভাবে সিআর, এলএফ এবং বিএস অক্ষর পাশাপাশি মাল্টবাইট ইউটিএফ -8 অক্ষরগুলি সরবরাহ করে (সরবরাহ iutf8করা আছে) তবে এটি প্রায় রয়েছে। এটি ধরে নিয়েছে যে সমস্ত অন্যান্য অ-নিয়ন্ত্রণের অক্ষর (শূন্য-প্রস্থ, ডাবল-প্রস্থের অক্ষর সহ) এর প্রস্থ 1 রয়েছে, এটি (স্পষ্টতই) পালানোর সিকোয়েন্সগুলি পরিচালনা করে না, সঠিকভাবে মোড়ায় না ... এটি সম্ভবত টার্মিনালের জন্যই উদ্দিষ্ট হয়েছে ট্যাব প্রসেসিং করতে পারবেন না।

যাই হোক না কেন, টিটি লাইনের শৃঙ্খলাটি সম্পর্কে কার্সারটি কোথায় রয়েছে তা জানতে হবে এবং উপরের সেই হিউরিস্টিকগুলি ব্যবহার করে, কারণ icanonলাইন সম্পাদক ব্যবহার করার সময় (যেমন আপনি যখন অ্যাপ্লিকেশনগুলির জন্য পাঠ্য প্রবেশ করেন যেমন catতাদের নিজস্ব লাইন সম্পাদক প্রয়োগ করেন না), আপনি যখন টিপুন TabBackspace, লাইনের শৃঙ্খলাটি জানতে হবে যে বিএস অক্ষর প্রদর্শনের জন্য সেই ট্যাব চরিত্রটি মোছার জন্য পাঠাতে হবে । আপনি যদি ট্যাব স্টপগুলি যেখানে থাকে (যেমন পছন্দ করেন tabs 12) তবে আপনি দেখতে পাবেন যে ট্যাবগুলি সঠিকভাবে মোছা হয়নি। আপনি চাপ দেওয়ার আগে ডাবল-প্রস্থের অক্ষর লিখলে একই TabBackspace


² তার জন্য, আপনি ট্যাব অক্ষরগুলি প্রেরণ করতে এবং প্রতিটিটির পরে কার্সারের অবস্থানটি জিজ্ঞাসা করতে পারেন। কিছুটা এইরকম:

tabs=$(
  saved_settings=$(stty -g)
  stty -icanon min 1 time 0 -echo
  gawk -vRS=R -F';' -vORS= < /dev/tty '
    function out(s) {print s > "/dev/tty"; fflush("/dev/tty")}
    BEGIN{out("\r\t\33[6n")}
    $NF <= prev {out("\r"); exit}
    {print sep ($NF - 1); sep=","; prev = $NF; out("\t\33[6n")}'
  stty "$saved_settings"
)

তারপরে, আপনি এটি expand -t "$tabs"@ কুসালানন্দের সমাধান হিসাবে ব্যবহার করতে পারেন ।


7
$ expand file | awk '{ print gsub(/ /, " ") }'
11
9
9

পসিক্স expandইউটিলিটিটি ট্যাবগুলিকে স্পেসে প্রসারিত করে। awkস্ক্রিপ্ট সংখ্যা এবং আউটপুট প্রতিটি লাইনে সব শূণ্যস্থান প্রতিস্থাপন করা প্রয়োজন বদল সংখ্যা।

ইনপুট ফাইলে কোনও পূর্ববর্তী স্থানের গণনা এড়াতে:

$ tr ' ' '@' <file | expand | awk '{ print gsub(/ /, " ") }'

@এমন একটি অক্ষর যেখানে ইনপুট ডেটাতে না থাকার গ্যারান্টিযুক্ত।

আপনি যদি সাধারণ 8 এর পরিবর্তে প্রতি ট্যাবে 10 স্থান চান:

$ tr ' ' '@' <file | expand -t 10 | awk '{ print gsub(/ /, " ") }'
9 
15
13

3
অন্যথায় xকল করার আগে আপনি স্পেসগুলি কিছু অন্য এক-প্রস্থের অক্ষরের (যেমন ) দিয়ে প্রতিস্থাপন করতে চান expand, আপনি প্রথমে ইনপুটটিতে শূণ্যস্থানগুলিও গণনা করছিলেন।
স্টাফেন চেজেলাস

1
expandপ্রতি 8 টি কলামে ট্যাব-স্টপগুলিও ধরে নেওয়া হয় (যদিও আপনি বিকল্পগুলির সাথে এটি পরিবর্তন করতে পারেন)। নোট করুন যে GNU বাস্তবায়ন মাল্টি-বাইট অক্ষরকে সমর্থন করে না (0-প্রস্থ বা ডাবল-প্রস্থের একক যাক)। আইআইআরসি ফ্রিবিএসডি ঠিক আছে।
স্টাফেন চেজেলাস

@ StéphaneChazelas, যদি না অবশ্যই, যে 0x20s ;-) দিয়ে 0x09s প্রস্থ গণনা পরিকল্পনার অংশ
যা করতে পারেন-ned_food

2

সহ perl:

perl -F/\\t/ -lpe '$c = 0; $F[-1] eq "" or pop @F; $_ = (map { $c += 8 - (length) % 8 } @F)[-1]' file

বিকল্পভাবে:

perl -MList::Util=reduce -lpe \
    '@F = split /\t/, $_, -1; pop @F if $F[-1] ne ""; $_ = reduce { $a + $b } map { 8 - (length) % 8 } @F' file

আপনি যদি ট্যাবগুলির পৃথক দৈর্ঘ্য চান তবে আপনি উপরের কয়েকটি মান সহ 8 টি পরিবর্তন করতে পারেন।


2

এছাড়াও ব্যবহার করছেন expand, তবে স্থানগুলির সংখ্যা গণনা করার জন্য ব্যাশ প্যারামিটার ম্যানিপুলেশন সহ:

$ line=$'field0\tfield00\tfield000\tlast-field'
$ tabs2spaces=$(expand <<<"$line")
$ only_spaces=${tabs2spaces//[^ ]/}    # remove all non-space characters
$ echo "${#only_spaces}"
11
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.