একটি স্ট্রিংয়ের সর্বশেষ 3 টি অক্ষর মুদ্রণের জন্য একটি আদেশ


30

আমি জানি যে cutকমান্ডটি nস্ট্রিংয়ের প্রথম অক্ষরগুলি মুদ্রণ করতে পারে তবে শেষ nঅক্ষরগুলি কীভাবে নির্বাচন করতে হয় ?

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

"সীমাহীন" আউটপুট প্রয়োজন "টেড"
"987654" আউটপুট প্রয়োজন "654"
"123456789" আউটপুট প্রয়োজন "789"

উত্তর:


52

কেন কেউ সুস্পষ্ট উত্তর দেয়নি?

sed 's/.*\(...\)/\1/'

… অথবা সামান্য কম স্পষ্ট

grep -o '...$'

স্বীকার করা হয় যে, দ্বিতীয়টির একটি অসুবিধা রয়েছে যা তিনটিরও কম অক্ষরের লাইনগুলি অদৃশ্য হয়ে যায়; তবে প্রশ্নটি এই মামলার আচরণের স্পষ্টভাবে সংজ্ঞা দেয়নি।


6
বাgrep -o '.\{3\}$'
অবিনাশ রাজ

3
বাecho "unlimited" | python -c "print raw_input()[-3:]"
কিরো

8
@ কিরো বা "echo unlimited" | java -jar EnterpriseWordTrimmer.jar, তবে আমি মনে করি না চরিত্রের হেরফেরের জন্য ভারী ভাষা আনা সত্যই প্রয়োজন।
wchargin

11
@WChargin আপনি ভুলে গেছেনjava -server -Xms300M -Xmx3G -XX:+UseParallelGC -cp /path/to/all/the/jars/ -Dinput.interactive=false -Dinput.pipe=true -Dconfig.file=/path/to/config/last-three-letters.cfg -jar ...
hjk

6
grep -o -P '.{0,3}$'লাইনটিতে 3 টিরও কম অক্ষর থাকলেও সর্বশেষ 3 টি অক্ষর মুদ্রণ করবে। -Pধনুর্বন্ধনী পালাতে হবে এড়ানো।
রঘু দোডা

43

এটি সহজ রাখা - লেজ

কেবল অক্ষর গণনা করার জন্য আমাদের নিয়মিত প্রকাশ বা একাধিক প্রক্রিয়া হওয়া উচিত নয়। প্রায়শই একটি ফাইলের শেষ লাইনগুলি প্রদর্শন করতে ব্যবহৃত
কমান্ডটিতে একটি বিকল্প ( ) থাকে যা এটির জন্য সঠিক সরঞ্জাম বলে মনে হচ্ছে:tail-c--bytes

$ printf 123456789 | tail -c 3
789

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

রিয়েল ইউনিকোডের অক্ষর?

এখন, আপনি শেষ তিনটি অক্ষর জিজ্ঞাসা করেছেন ; এই উত্তরটি আপনাকে যা দেয় তা নয়: এটি শেষ তিনটি বাইট ছাড়িয়ে যায় !

যতক্ষণ না প্রতিটি চরিত্র একটি বাইট হয় tail -cকেবল কাজ করে। সুতরাং এটি ব্যবহার করা যেতে পারে যদি অক্ষর সেট হয় ASCII, ISO 8859-1বা বৈকল্পিক হয়।

আপনার যদি সাধারণ UTF-8বিন্যাসের মতো ইউনিকোড ইনপুট থাকে তবে ফলাফলটি ভুল:

$ printf 123αβγ | tail -c 3
�γ

এই উদাহরণস্বরূপ, UTF-8গ্রীক অক্ষর আলফা, বিটা এবং গামা দুটি বাইট দীর্ঘ:

$ printf 123αβγ | wc -c  
9

বিকল্পটি -mকমপক্ষে প্রকৃত ইউনিকোড অক্ষর গণনা করতে পারে:

printf 123αβγ | wc -m
6

ঠিক আছে, সুতরাং শেষ 6 বাইট আমাদের শেষ 3 অক্ষর দেবে:

$ printf 123αβγ | tail -c 6
αβγ

সুতরাং, tailসাধারণ অক্ষরগুলি পরিচালনা করার পক্ষে সমর্থন করে না এবং এটি চেষ্টাও করে না (নীচে দেখুন): এটি পরিবর্তনশীল আকারের লাইনগুলি পরিচালনা করে, তবে কোনও ভেরিয়েবল আকারের অক্ষরগুলিকে পরিচালনা করে না।

আসুন এটি এইভাবে রাখুন: tailসমস্যার সমাধানের কাঠামোর পক্ষে ঠিক সঠিক, তবে ডেটা ধরণের জন্য ভুল।

জিএনইউ কোর্টিলস

আরও খুঁজছি, এটা দেখা যাচ্ছে যে তোমাকে গনুহ coreutils, মৌলিক সরঞ্জাম সংগ্রহ পছন্দ sed, ls, tailএবং cut, এখনো সম্পূর্ণরূপে আন্তর্জাতিকিকরনকৃত করা হয় না। যা মূলত ইউনিকোডকে সমর্থন করার বিষয়ে।
উদাহরণস্বরূপ, cutঅক্ষর সমর্থনের জন্য এখানে লেজের পরিবর্তে ব্যবহার করা ভাল প্রার্থী হবে; এটিতে বাইট বা চরগুলি নিয়ে কাজ করার বিকল্প রয়েছে, -c( --bytes) এবং -m( --chars);

সংস্করণ , 2013 হিসাবে কেবলমাত্র -m/ তা বাস্তবায়িত হয়নি!--chars
cut (GNU coreutils) 8.21

থেকে info cut:

`-c CHARACTER-LIST'
`--characters=CHARACTER-LIST'
     Select for printing only the characters in positions listed in CHARACTER-LIST.  
     The same as `-b' for now, but internationalization will change that.


এই উত্তরটি দেখুন ইউটিএফ -8 এর সাথে `কাট-সি` (` --characters`) ব্যবহার করতে পারবেন না?


2
প্রকৃতপক্ষে, অন্যান্য উত্তরগুলির বেশিরভাগই ইউনিকোডকে ঠিক ঠিক পরিচালনা করবে, যতক্ষণ না বর্তমান লোকাল ইউটিএফ -8 এনকোডিং নির্দিষ্ট করে। কেবল আপনার এবং গ্লেন জ্যাকম্যান- cutভিত্তিক সমাধান মনে হয় না।
ইলমারি করোনেন

@ ইলমারিকারোনেন সত্য, ইঙ্গিতটির জন্য ধন্যবাদ। আমি অতিরিক্ত কিছু বিশদ সহ সম্পাদনা করেছি।
ভোলকার সিগেল

1
নোট করুন যে পসিক্স স্পষ্টভাবে নির্দিষ্ট করে যা tailবাইটগুলির সাথে ডিল করা উচিত, না চরিত্রগুলির সাথে and আমি একবারে অক্ষর বাছাই করতে একটি নতুন বিকল্প যুক্ত করার জন্য একটি প্যাচ তৈরি করেছি, তবে আমি বিশ্বাস করি যে কখনও মিশে যায় নি: - /
মার্টিন টর্নয়েজ

ফাইল-মোডে কাজ করে না, যেমনtail -c3 -n10 /var/log/syslog
সানক্যাচার

@ সানকাচার আমি চেষ্টা করেছিলাম, এবং এটি কার্যকর হয়েছিল। কী সমস্যা দেখছেন? আপনার আদেশটি tail -c3 -n10 /var/log/syslog10 টি লাইন জিজ্ঞাসা করেছে এবং এটি আমার পক্ষে কাজ করে। আপনি বিকল্পটি ব্যবহার করুন -c3এবং এর পরে বিরোধী বিকল্পটি -n10। পরবর্তী বিকল্পটি অগ্রাধিকার নেয়।
ভোলকার সিগেল

36

যদি আপনার পাঠ্যটি শেল ভেরিয়েবল নামে পরিচিত হয় তবে STRINGআপনি এটি bash, zshবা mkshশেলের মাধ্যমে এটি করতে পারেন :

printf '%s\n' "${STRING:(-3)}"

অথবা

printf '%s\n' "${STRING: -3}"

যেটির সিনট্যাক্সটি আসে যেখানে ksh93 এর সাথে কাজ করার সুবিধাও রয়েছে।

মুল বক্তব্যটি হল যে এর :থেকে পৃথক করতে হবে -, অন্যথায় এটি ${var:-default}বোর্ন শেলের অপারেটর হয়ে যায় ।

zshবা yashশাঁসের সমতুল্য বাক্য গঠন :

printf '%s\n' "${STRING[-3,-1]}"

2
এই জাতীয় সিনট্যাক্স / অপারেশনটি কী বলা হয় যাতে আমি আরও তথ্য অনুসন্ধান করতে পারি?
তুলিনাস কর্ডোভা

6
একে সাবস্ট্রিং এক্সপেনশন বলা হয় । এটি এক ধরণের প্যারামিটার সম্প্রসারণ । সাধারণ ফর্মটি হ'ল {{পরামিতি: অফসেট: দৈর্ঘ্য} , তবে দৈর্ঘ্যের ক্ষেত্রটি optionচ্ছিক (এবং আপনি দেখতে পাচ্ছেন যে এটি উপরের উত্তরে বাদ দেওয়া হয়েছে)। ডোপগোটিও ${STRING:(-3):3}( দৈর্ঘ্যের ক্ষেত্র নির্দিষ্ট করে ), ${STRING: -3}(এবং :এবং এর মধ্যে একটি স্থান সহ ) লিখতে পারত -বা ${STRING: -3:3}
জি-ম্যান

এই ক্ষেত্রে, দৈর্ঘ্যটি নির্দিষ্ট 3করা কিছুটা গতিযুক্ত যেহেতু "শেষ চরিত্র থেকে তৃতীয় থেকে তিনটি অক্ষর, অন্তর্ভুক্ত" জন্য জিজ্ঞাসা করছে যা ব্যবহারিক দিক থেকে অভিন্ন ক্রিয়াকলাপ হিসাবে দেখা যায় "শেষ থেকে তৃতীয় থেকে সমস্ত অক্ষর , অন্তর্ভুক্ত".
ডোপঘোতি

13

ব্যবহার awk:

awk '{ print substr( $0, length($0) - 2, length($0) ) }' file
ted
654
789

11

যদি স্ট্রিংটি ভেরিয়েবলের হয় তবে আপনি এটি করতে পারেন:

printf %s\\n "${var#"${var%???}"}"

এটি লাইকের মান থেকে শেষ তিনটি অক্ষরকে বাদ দেয় $var:

${var%???}

... এবং তারপরে $varসমস্ত কিছুর মাথার দিক থেকে ফেলা যা কেবল যেমন ছিনিয়ে নেওয়া হয়েছিল:

${var#"${var%???}"}

এই পদ্ধতিতে এর উত্সাহ এবং ডাউনসাইড রয়েছে। উজ্জ্বল দিকে এটি পুরোপুরি পসিক্স-বহনযোগ্য এবং কোনও আধুনিক শেলটিতে কাজ করা উচিত। এছাড়াও, যদি $varঅন্তত তিনটি অক্ষর না থাকে তবে পিছনে থাকা \nইলাইনটি প্রিন্ট করা ছাড়া কিছুই নয় । তারপরে আবারও, আপনি যদি সেক্ষেত্রে এটি মুদ্রিত করতে চান তবে আপনার অতিরিক্ত ধাপের দরকার যেমন:

last3=${var#"${var%???}"}
printf %s\\n "${last3:-$var}"

এভাবে $last3শুধুমাত্র কখনও খালি যদি $var3 বা তার চেয়ে কম বাইট ধারণ করে। এবং $varকেবলমাত্র $last3যদি $last3খালি হয় বা এর জন্য প্রতিস্থাপিত হয় unset- এবং আমরা জানি যে এটি unsetকেবলমাত্র এটি সেট করার কারণে নয়।


এটি বেশ পরিপাটি +1। পাশে: কোনও কারণ আপনি আপনার printfফর্ম্যাট স্ট্রিং উদ্ধৃতি না ?
জেসনওয়ারিয়ান

শুধু ব্যবহার ${VARNAME:(-3)}(অনুমান bash) কেন করবেন না ?
ডোপঘোতি

1
স্পষ্ট করার জন্য ধন্যবাদ; কিছুটা অদ্ভুত
লাগলেও

1
@ ডোপগোতি - কেবলমাত্র এমন একটি ধারণা যা আমি প্রায় কখনও করি না। এটি bashপসিক্স কোমাপিবিলিটি দাবি করার মতো অন্য কোনও শেলের মতো কাজ করে।
মাইকজার্ভ

3
@odyssey - সমস্যা cshনেই না মধ্যে আধুনিক, POSIX সামঞ্জস্যপূর্ণ শাঁস আমি এখানে উল্লেখ, দুর্ভাগ্যবশত। পসিক্স-শেল স্পেক পরে মডেল করা হয় ksh, যা উভয় cshএবং theতিহ্যবাহী বোর্ন-স্টাইল শেলগুলির সংমিশ্রনের পরে নিজেকে মডেল করে তোলে। kshউভয়ের cshদুর্দান্ত কাজের-নিয়ন্ত্রণ কার্যকারিতা এবং পুরাতন বোর্ন-শৈলীগুলির আই / ও পুনঃনির্দেশ উভয়কেই অন্তর্ভুক্ত করেছে । এটি কিছু জিনিস যুক্ত করেছে - যেমন স্ট্রিং ম্যানিপুলেশন ধারণাগুলি আমি উপরে প্রদর্শন করি। cshযতদূর আমি জানি এটি কোনও প্রথাগতভাবে সম্ভবত কাজ করবে না , আমি দুঃখের সাথে বলতে চাই।
মাইক্রজারভ


3

Utf-8 স্ট্রিংয়ের বুলেটপ্রুফ সমাধান:

utf8_str=$'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' # привет

last_three_chars=$(perl -CAO -e 'print substr($ARGV[0], -3)' "$utf8_str")

বা ব্যবহার করুন:

last_three_chars=$(perl -MEncode -CO -e '
  print substr(decode("UTF-8", $ARGV[0], Encode::FB_CROAK), -3)
' "$utf8_str")

ত্রুটিযুক্ত ডেটা হ্যান্ডলিং রোধ করতে।

উদাহরণ:

perl -MEncode -CO -e '
  print substr(decode("UTF-8", $ARGV[0], Encode::FB_CROAK), -3)
' $'\xd0\xd2\xc9\xd7\xc5\xd4' # koi8-r привет

এরকম কিছু আউটপুট দেয়:

utf8 "\xD0" does not map to Unicode at /usr/lib/x86_64-linux-gnu/perl/5.20/Encode.pm line 175.

স্থানীয় সেটিংসের উপর নির্ভর করে না (যেমন এর সাথে কাজ করে LC_ALL=C)। Bash, sed, grep, awk, revভালো কিছু প্রয়োজন:LC_ALL=en_US.UTF-8

সাধারণ সমাধান:

  • বাইট গ্রহণ করুন
  • এনকোডিং সনাক্ত করুন
  • অক্ষরে ডিকোড বাইট
  • চরিত্রগুলি বের করুন
  • বাইটগুলিতে অক্ষর এনকোড করুন

আপনি ucardet সহ এনকোডিং সনাক্ত করতে পারেন । আরও দেখুন সংক্রান্ত প্রকল্পগুলোতে

আপনি পার্লের এনকোড , পাইথন ২.7 এ কোডেক সহ ডিকোড / এনকোড করতে পারেন

উদাহরণ :

Utf-16le স্ট্রিং থেকে শেষ তিনটি অক্ষর বের করুন এবং এই অক্ষরগুলিকে utf-8 এ রূপান্তর করুন

utf16_le_str=$'\xff\xfe\x3f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42\x04' # привет

chardet <<<"$utf16_le_str"  # outputs <stdin>: UTF-16LE with confidence 1.0

last_three_utf8_chars=$(perl -MEncode -e '
    my $chars = decode("utf-16le", $ARGV[0]);
    my $last_three_chars = substr($chars, -3);
    my $bytes = encode("utf-8", $last_three_chars);
    print $bytes;
  ' "$utf16_le_str"
)

আরও দেখুন: পার্লুনিটুট , পাইথন 2 ইউনিকোড হাটো


echoআপনার বুলেটপ্রুফ উত্স?
মাইকসার্ভ

@ মাইকজার্ভ, decode/encodeআমার বুলেটপ্রুফ উত্স। আমার উত্তর পরিষ্কার।
ইভজেনি ভেরেশচাগিন

এটি সঠিকভাবে কাজ করে তার গ্যারান্টি দেওয়ার জন্য এটি স্থানীয় সেটিংসের উপরও নির্ভর করে, যেহেতু বাইটের একটি সেট বিভিন্ন অক্ষরে বিভিন্ন অক্ষরকে প্রতিবিম্বিত করতে পারে। এটি "কাজ করে" LC_ALL=Cকারণ এটি একটি খুব "বোবা" সেটিং, তবে আপনি যখন ইউটিএফ -8 স্ট্রিংটি শিফট -5, বা একটি শিফট -5 স্ট্রিং
কেওআই

@ কার্পেটস্মোকার, ধন্যবাদ আপনি আপনার মন্তব্য ব্যাখ্যা করতে পারেন? আমি মনে করি যে এটি perl -CAO -e 'print substr($ARGV[0], -3)'ঠিক আছে। A@ARGV উপাদানগুলি ইউটিএফ -8 এ স্ট্রিং এনকোড করা হবে বলে আশা করা হচ্ছে, STDOUT OUTF-8 এ থাকবে।
ইভজেনি ভেরেশচাগিন

দেখে মনে হচ্ছে আপনি নিয়োগ সম্পর্কে বলছেনutf8_str
এভজেনি ভেরেশচাগিন

1

"এক্সপ্রেস" বা "রেভ" ব্যবহার সম্পর্কে কী?

@ জি-ম্যান দ্বারা প্রদত্ত অনুরূপ একটি উত্তর : expr "$yourstring" : '.*\(...\)$' গ্রিপ সমাধানের তুলনায় এর একই অপূর্ণতা রয়েছে।

একটি পরিচিত কৌশলটি "কাটা" "" রেভ "এর সাথে একত্রিত করা: echo "$yourstring" | rev | cut -n 1-3 | rev



আপনি ঠিক বলেছেন @ জেফ_স্যাচলার: আমি গ্লেনের একটিকে মিস করেছি :-(
গিলডাক্স

0

এর সাথে স্ট্রিংয়ের আকার পান:

size=${#STRING}

তারপরে সর্বশেষ এন অক্ষরের সাবস্ট্রিং পান:

echo ${STRING:size-n:size}

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

STRING=123456789
n=3
size=${#STRING}
echo ${STRING:size-n:size}

দিতে হবে:

789

0

লেজ -n 1 রিভিশনস.লগ | awk 'sub মুদ্রণ সাবস্ট্রিট ($ 0, 0, দৈর্ঘ্য ($ 0) - (দৈর্ঘ্য ($ 0) -13))}'

আপনি যদি প্রথম তেরো অক্ষরটি প্রারম্ভিক থেকে মুদ্রণ করতে চান


-1

স্ট্রিংয়ের ফাঁকা স্থান থাকলে প্রিন্টফ কাজ করবে না।

স্থান সহ স্ট্রিংয়ের জন্য কোডের নীচে

str="Welcome to Linux"
echo -n $str | tail -c 3

nux


ওম, যদি printfকাজ না করে, তবে আপনি খুব ভুল কিছু করছেন ।
কুসালানন্দ

1
@ কুসালানন্দ: সৌরভ যে আদেশটি দেখিয়েছে তার উপর ভিত্তি করে তারা চেষ্টা করেছিল printf $str(বরং printf "$str"বা তার চেয়ে বেশি printf '%s' "$str")। আর, হ্যাঁ, printf $strহয় খুব ভুল। (এর echo -n $strচেয়ে ভাল কিছু নয়))
জি-ম্যান বলেছেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.