শেল স্ক্রিপ্টিংয়ে স্ট্রিংয়ের প্রথম দুটি অক্ষর কীভাবে নিষ্কাশন করা যায়?


123

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

USCAGoleta9311734.5021-120.1287855805

আমি কেবল নিষ্কাশন করতে চাই:

US

6
ধন্যবাদ সবাইকে. আমি 'কাটা -c1-2' ব্যবহার করে শেষ করেছি, সত্যি বলতে আমি 'কাট' সেখানে জানতাম না। আমি বলতে চাই যে আমি কমান্ড লাইনে বেশ অভিজ্ঞ - তবে স্পষ্টতই আমার অনেক কিছু শেখার আছে।
গ্রেগ

1
@ গ্রেগ, কেবল সচেতন থাকুন যে কাটাটি পৃথক প্রক্রিয়া হিসাবে চালিত হয় - এটি আমার উত্তরে আমি পাশাপাশি পোস্ট করা অভ্যন্তরীণ-ব্যাশ সমাধানের চেয়ে ধীর হবে। আপনি বিশাল ডেটা সেটগুলি প্রক্রিয়া না করা ছাড়া এটি কোনও তত্পরতা ফেলবে না তবে আপনাকে এটি মাথায় রাখা দরকার।
paxdiablo

আসলে সম্পাদনা করুন , আমি মনে করি কোডটির এই লাইনটি সম্ভবত প্রতি প্রতি প্রায় 50,000 বার কার্যকর করা হবে। সুতরাং আমি কেবল অভ্যন্তরীণ বাশ পদ্ধতির সাথে যেতে পারি - যা আপনি বলেছিলেন কিছু প্রয়োজনীয় সংস্থান সংরক্ষণ করবে।
গ্রেগ

উত্তর:


180

সম্ভবত সবচেয়ে কার্যকর পদ্ধতি, যদি আপনি bashশেলটি ব্যবহার করেন (এবং আপনি আপনার মন্তব্যের উপর ভিত্তি করে উপস্থিত হন), প্যারামিটার বিস্তারের সাব-স্ট্রিং বৈকল্পিকটি ব্যবহার করা:

pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US

এটি shortপ্রথম দুটি চরিত্র হতে সেট করবে long। যদি longদুটি চরিত্রের চেয়ে কম shortহয় তবে এটির জন্য অভিন্ন হবে।

শেল-ইন-শেল পদ্ধতিটি সাধারণত ভাল হয় যদি আপনি এটি প্রচুর পরিমাণে করতে যাচ্ছেন (প্রতিবেদনের প্রতি 50,000 বারের মতো) যেহেতু কোনও প্রক্রিয়া ওভারহেড নেই। বাহ্যিক প্রোগ্রামগুলি ব্যবহার করে এমন সমস্ত সমাধান সেই ওভারহেডে ভুগবে।

আপনি যদি ন্যূনতম দৈর্ঘ্যও নিশ্চিত করতে চেয়েছিলেন তবে আপনি আগে এমন কিছু দিয়ে তা প্যাড করতে পারেন:

pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.

এটি নিশ্চিত করবে যে দৈর্ঘ্যের দুটি অক্ষরের চেয়ে কম যে কোনও কিছুকে পিরিয়ড সহ ডানদিকে প্যাড করা হয়েছিল (বা অন্য কিছু, ঠিক তৈরির সময় ব্যবহৃত চরিত্রটি পরিবর্তন করে tmpstr)। আপনার এটি প্রয়োজন তা পরিষ্কার নয় তবে আমি ভেবেছিলাম এটি সম্পূর্ণতার জন্য রেখে দেব।


এটি বলার পরেও, বাহ্যিক প্রোগ্রামগুলির সাথে এটি করার অনেকগুলি উপায় রয়েছে (যেমন যদি আপনার কাছে bashউপলব্ধ না থাকে ), এর কয়েকটি হল:

short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')

প্রথম দুটি ( cutএবং head) একক লাইন স্ট্রিংয়ের জন্য অভিন্ন - এগুলি মূলত উভয়ই আপনাকে প্রথম দুটি অক্ষর ফিরিয়ে দেয়। এগুলির মধ্যে এটির ভিন্নতা cutআপনাকে প্রতিটি লাইনের headপ্রথম দুটি অক্ষর দেবে এবং আপনাকে পুরো ইনপুটটির প্রথম দুটি অক্ষর দেবে

তৃতীয়টি awkপ্রথম দুটি অক্ষর নিষ্কাশন করতে সাব-স্ট্রিং ফাংশন sedব্যবহার করে ()এবং চতুর্থটি প্রথম দুটি অক্ষর ক্যাপচারের জন্য ক্যাপচার গ্রুপগুলি (ব্যবহার করে \1) ব্যবহার করে এবং তাদের সাথে পুরো লাইনটি প্রতিস্থাপন করে। এগুলি উভয়ের মতোই cut- তারা ইনপুটটিতে প্রতিটি লাইনের প্রথম দুটি অক্ষর সরবরাহ করে।

আপনার ইনপুটটি একটি একক লাইন কিনা তা নিশ্চিত হয়ে থাকলে সেগুলির মধ্যে কোনওটিই বিবেচনা করে না, সেগুলির একটিরই অভিন্ন প্রভাব রয়েছে।


আমি বরং ব্যবহার করেন printf '%s'পরিবর্তে echoক্ষেত্রে সেখানে স্ট্রিং অদ্ভুত অক্ষর আছেন: stackoverflow.com/a/40423558/895245 POSIX জন্য অন্ধকারাচ্ছন্ন: head -cPOSIX নয়, cut -cএবং awk substrহয়, sed \1নিশ্চিত না।
সিরো সান্তিলি 法轮功 冠状 病 六四 事件 法轮功

1
@CiroSantilli print 改造 中心 996ICU print print প্রিন্টফ ব্যবহার করে, আপনার এমনকি কোনও অতিরিক্ত প্রোগ্রামের প্রয়োজন নেই। আমার উত্তর দেখুন ।
bschlueter

60

সবচেয়ে সহজ উপায়

${string:position:length}

যেখানে এ $lengthথেকে সাবস্ট্রাক্ট ।$string$position

এটি একটি বাশ অন্তর্নির্মিত তাই তাই বাজে বা শেড প্রয়োজন হয় না।


এটি সংক্ষিপ্ত, মিষ্টি এবং সহজতম পদ্ধতিতে স্ট্রিংগুলি পান।
ani627

34

আপনি বেশ কয়েকটি ভাল উত্তর পেয়েছেন এবং আমি নিজেই বাশ বিল্টিনের সাথে যাব, তবে আপনি যেহেতু জিজ্ঞাসা করেছিলেন sedএবং awkএবং ( প্রায় ) অন্য কেউ তাদের ভিত্তিতে সমাধানের প্রস্তাব দেয় না, আমি আপনাকে এই অফার দিচ্ছি:

echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'

এবং

echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'

awkএক মোটামুটি সুস্পষ্ট করা কর্তব্য, কিন্তু এখানে একটি ব্যাখ্যা আছে sedএক:

  • বিকল্প "এস /"
  • ")" লাইনের শুরুতে এবং "" কোনও অক্ষরের দুটি "এর গ্রুপ" () "এবং তার পরে কোনও অক্ষর" "" " শূন্য বা তার বেশি বার পুনরাবৃত্তি "*" (কিছু বিশেষ অক্ষর থেকে বাঁচতে ব্যাকস্ল্যাশগুলি প্রয়োজন)
  • "/" দ্বারা প্রথম (এবং কেবলমাত্র এই ক্ষেত্রে) গ্রুপের বিষয়বস্তু (এখানে ব্যাকস্ল্যাশটি একটি বিশেষ পলায়ন যা কোনও মিলের উপ-এক্সপ্রেশনকে বোঝায়)
  • সম্পন্ন "/"

1
ডাবের স্ট্রিং ইনডেক্স 1 এ শুরু হয়, সুতরাং আপনার ব্যবহার করা উচিত substr($0,1,2)
আইজ্যাক

8

আপনি যদি ভিতরে থাকেন তবে আপনি bashবলতে পারেন:

bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab

এটি আপনার প্রয়োজন কেবল হতে পারে ...


সবচেয়ে সহজ এবং সবচেয়ে সহজ উত্তর! মোহন মত কাজ করেছেন
ahaha

7

শুধু গ্রেপ:

echo 'abcdef' | grep -Po "^.."        # ab

আমার প্রয়োজন ফিট করে। -Pএটি সংক্ষিপ্ত করার বিকল্পটি আপনি মুছে ফেলতে পারেন । সমস্ত রেজেক্সগুলি সেই প্যাটার্নটি বুঝতে পারবে।
দতাশমন

6

আপনি ব্যবহার করতে পারেন printf:

$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US

5

কলারম - একটি ফাইল থেকে কলামগুলি সরান

প্রথম দুটি অক্ষর ছেড়ে যেতে, কেবল 3 থেকে শুরু করে কলামগুলি সরিয়ে ফেলুন

cat file | colrm 3


2

আপনি যদি শেল স্ক্রিপ্টিং ব্যবহার করতে চান এবং নন-পিক্সিক এক্সটেনশনগুলিতে (যেমন তথাকথিত বাশিজম) উপর নির্ভর না করে থাকেন তবে আপনি এমন কৌশল ব্যবহার করতে পারেন যেগুলি গ্রিপ, সেড, কাট, অ্যাজক ইত্যাদির মতো বাহ্যিক সরঞ্জামগুলি কাঁটাচামচ করার প্রয়োজন হয় না, যা পরে আপনার স্ক্রিপ্ট কম দক্ষ করুন। আপনার দক্ষতা এবং পিক্সের বহনযোগ্যতা আপনার ব্যবহারের ক্ষেত্রে গুরুত্বপূর্ণ নয়। তবে এটি (বা কেবল একটি ভাল অভ্যাস হিসাবে) ক্ষেত্রে, আপনি শেল ভেরিয়েবলের প্রথম দুটি অক্ষর নিষ্কাশন করতে নিম্নলিখিত প্যারামিটার সম্প্রসারণ বিকল্প পদ্ধতিটি ব্যবহার করতে পারেন :

$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab

প্রথম দুটি অক্ষর (এটি অংশ) মুছে ফেলার জন্য এটি "ক্ষুদ্রতম উপসর্গ" পরামিতি সম্প্রসারণ ব্যবহার করে ${var#??}, তারপরে "ক্ষুদ্রতম প্রত্যয়" পরামিতি সম্প্রসারণ ( ${var%অংশ) সেই সমস্ত-তবে-প্রথম-দুটি-অক্ষরের স্ট্রিংটি মূল থেকে সরান মান।

এই পদ্ধতিটি পূর্বে "শেল = উত্তর দিয়ে ভেরিয়েবল #" দিয়ে শুরু হয় কিনা তা এই উত্তরটিতে বর্ণিত ছিল । এই উত্তরটি কয়েকটি দু'জনের অনুরূপ প্যারামিটার সম্প্রসারণের পদ্ধতিও বর্ণনা করে যা এখানে কিছুটা ভিন্ন প্রসঙ্গে ব্যবহার করা যেতে পারে যা এখানে মূল প্রশ্নের ক্ষেত্রে প্রযোজ্য।


সেরা উত্তর, শীর্ষে থাকা উচিত। কোন কাঁটাচামচ নেই, বাশিজম নেই। এমনকি ছোট ছোট শাঁস যেমন ড্যাশ দিয়েও কাজ করে।
পূর্বোক্ত

1

আপনার সিস্টেমে একটি ভিন্ন শেল (শুধুমাত্র ব্যবহার করা হয়, তাহলে bash), কিন্তু আপনার সিস্টেম আছে bash, তাহলে আপনি এখনও সহজাত স্ট্রিং ম্যানিপুলেশন ব্যবহার করতে পারেন bashআবাহন করার মাধ্যমে bashএকটি পরিবর্তনশীল সঙ্গে

strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"

এটি মূল উত্তর হিসাবে একই পদ্ধতি ব্যবহার করে , কেবলমাত্র অনুরোধ করা bashযদি আপনি ইতিমধ্যে এটি ব্যবহার না করে থাকেন।
পালসুইম

দুর্ভাগ্যক্রমে, এটি অন্য সমস্ত প্রক্রিয়া ডাকে সমস্ত ওভারহেডের সাথে আসে, তবে কখনও কখনও যে ওভারহেড সরলতা এবং পরিচিতি হিসাবে ততটা গুরুত্ব দেয় না।
পালসুইম

1

কেবল মজাদার উদ্দেশ্যেই ইল কয়েকটি যোগ করুন, যদিও এগুলি জটিল এবং অকেজো হয়ে গেছে, তাদের উল্লেখ করা হয়নি:

head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')

echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none

sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')

cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')

python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"

ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'


0

যদি মাইস্ট্রিং = ইউএসসিএজিওলেটা 9311734.5021-120.1287855805

print substr(mystring,0,2)

মার্কিন মুদ্রণ হবে

যেখানে 0 হল শুরুর অবস্থান এবং 2 হল মেনী চরগুলি কীভাবে পড়তে হয়


বলুন ... যে GW-বেসিক না? ওহ, অপেক্ষা করুন awk। দুঃখিত, আমি প্রথমে বলতে পারিনি।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

0

এই কি আপনার পরে?

my $string = 'USCAGoleta9311734.5021-120.1287855805';

my $first_two_chars = substr $string, 0, 2;

রেফ: সাবস্ট্রিট


1
প্রদত্ত যে শেলটি থেকে তিনি সম্ভবত এই কল করছেন, আরও ভাল ফর্মটি হবেperl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'
চস। ওয়েন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.