রেঞ্জ ব্যবহার করে ট্রের অদ্ভুত আচরণ


10

আমার একটি বিশেষ সার্ভার রয়েছে যা ট্র ব্যবহার করার সময় অদ্ভুত আচরণ প্রদর্শন করে। এখানে একটি ওয়ার্কিং সার্ভারের একটি উদাহরণ:

-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$

এটা আমার নিখুঁত জ্ঞান করে তোলে।

এটি অবশ্য 'বিশেষ' সার্ভার থেকে এসেছে:

[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890

আপনি দেখতে পাচ্ছেন, সমস্ত ছোট ছোট অক্ষর মুছে ফেলা ব্যর্থ হয়। তবে এটি 'ও' অক্ষরটি মুছে ফেলেছে

আকর্ষণীয় অংশটি নিম্নলিখিত দুটি উদাহরণ, যা আমার কাছে কোনও ধারণা রাখে না:

[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#

(আবার, 'শেষ' উদাহরণে মুছে ফেলা হয়)

এখানে কি চলছে কারও কি ধারণা আছে? আমি যে অন্য লিনাক্স বাক্সটি ব্যবহার করছি তা পুনরুত্পাদন করতে পারি না।


5
Tangentially সম্পর্কিত: trরেঞ্জ এনক্লোজিং ছাড়া লেখা হয় [...]। সুতরাং tr -d '[a-z]'মেরে ফেলবে a-z, এবং চরিত্র [এবং ]tr -d a-zকেবলমাত্র অক্ষরগুলি মারতে ব্যবহার করুন a-z
স্যাট কাটসুরা

উত্তর:


24

আপনার oবর্তমান ডিরেক্টরিতে একটি ফাইল রয়েছে

foo> ls
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
foo> touch o
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890

[a-z]কোনও মিল পাওয়া গেলে শেল স্ট্রিং প্রসারিত করবে ।

অনুসারে এটিকে বলা হয় পথের নাম সম্প্রসারণ man bash

পথের নাম সম্প্রসারণ
শব্দের বিভাজনের পরে -f বিকল্পটি সেট না করা থাকলে, ব্যাশ প্রতিটি শব্দ *,?, এবং [এর জন্য স্ক্যান করে। ... (...)

বাশ সম্প্রসারণ করবে।

[...] বদ্ধ অক্ষরের যে কোনও একটির সাথে মিলে।


@ ক্রিস আপনি উদাহরণস্বরূপ শেলটির সম্প্রসারণ পরীক্ষা করতে পারেন echo: touch o ; echo tr -d [a-z]এটি দেয়:tr -d o
পাবুক

8

কি হচ্ছে

শেল (বাশ) আর্গুমেন্টটি দেখে [a-z]। এটা একটা ওয়াইল্ডকার্ড প্যাটার্ন (ক এর উল্লিখিত glob ), যা যে কোন ছোট হাতের letter¹ সাথে মেলে। সুতরাং শেলটি এই প্যাটার্নটির সাথে মেলে এমন কোনও ফাইলের নাম সন্ধান করে। তিনটি মামলা রয়েছে:

  • বর্তমান ডিরেক্টরিতে কোনও ফাইলের একটিই নাম নেই যা একটি একক ছোট হাতের অক্ষর। তারপরে শেলটি ওয়াইল্ডকার্ডের প্যাটার্নটি অপরিবর্তিত রেখে দেয় এবং trআর্গুমেন্টগুলি -dএবং দেখে [a-z]। আপনার বেশিরভাগ মেশিনে এটিই ঘটে।
  • বর্তমান ডিরেক্টরিতে একটি একক ফাইলের একটি নাম রয়েছে যা একটি একক ছোট হাতের অক্ষর। তারপরে শেলটি এই ফাইলটির নামের সাথে প্যাটার্নটি প্রসারিত করে এবং trআর্গুমেন্ট -dএবং ফাইলের নামটি দেখে। এটি সার্ভারে ঘটে এবং ম্যাচিং ফাইলটি কল করা হয় oকারণ আমরা দেখতে পাচ্ছি যে trচিঠিটি মুছে ফেলা হয়েছে o
  • বর্তমান ডিরেক্টরিতে দুটি বা আরও বেশি ফাইলের একটি নাম রয়েছে যা একটি একক ছোট হাতের অক্ষর। তারপরে শেলটি মিলে যাওয়া ফাইলের নামের তালিকায় প্যাটার্নটি প্রসারিত করে এবং trতিন বা ততোধিক যুক্তি দেখায়: -dএবং ফাইলের নাম। যেহেতু trপরে একটি একক যুক্তি প্রত্যাশা করে -d, এটি অভিযোগ করবে।

আপনার কি করা উচিত ছিল

কোনও কমান্ডের যুক্তিতে যদি বিশেষ অক্ষর থাকে তবে আপনাকে অবশ্যই সেগুলি থেকে পালাতে হবে। যুক্তিটি একক উদ্ধৃতিতে রাখুন '…'(এটি সহজতম উপায়, অন্যগুলি রয়েছে)) একক উদ্ধৃতিগুলির ভিতরে, সমস্ত অক্ষর একক উদ্ধৃতি নিজেই বাদ দিয়ে নিজের পক্ষে দাঁড়ায়। আর্গুমেন্টের ভিতরে যদি একটি একক উক্তি থাকে তবে এটি দ্বারা প্রতিস্থাপন করুন'\''

tr -d '[a-z]'

তবে মনে রাখবেন যে এটি সম্ভবত আপনি বোঝাতে চেয়েছিলেন না! এটি trছোট হাতের অক্ষর এবং স্কোয়ার বন্ধনীগুলি মুছতে বলে । এটা তোলে সমতুল্য tr -d ']a-z[', tr '[]a-z'ছোট হাতের অক্ষর মুছে ফেলার জন্য, ইত্যাদি, ব্যবহার

tr -d a-z

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

চরিত্রের ক্লাসগুলি নির্দেশ করতে আপনার ব্র্যাকেটগুলির দরকার নেই । একটি নিয়মিত অভিব্যক্তি হিসাবে, আপনি একটি অক্ষর শ্রেণি নির্দেশ করতে বন্ধনীগুলির মধ্যে বন্ধনী ব্যবহার করেন, উদাহরণস্বরূপ যে [[:lower:]]*কোনও সংখ্যার ছোট অক্ষরের সাথে [[:lower:]_]*মেলে, কোনও সংখ্যার ছোট অক্ষর এবং আন্ডারস্কোরের সাথে মেলে। যুক্তি অনুসারে trআপনার আশেপাশের বন্ধনীগুলি ছাড়াই সেটটি প্রয়োজন, সুতরাং tr -d '[:lower:]'ছোট হাতের অক্ষর tr -d '[:lower:]_'মুছে ফেলা, ছোট হাতের অক্ষর এবং আন্ডারস্কোরগুলি মুছে ফেলা ইত্যাদি

Some কিছু লোকেলে এটি অন্য অক্ষরের সাথে মেলে


1
নোট করুন যে সোলারিস 10 (এবং অন্যান্য প্রাচীন এসআইএসভি ভিত্তিক ইউনিসিস) এ আপনার দরকার tr -d '[a-z]'পড়ে /usr/bin/tr। সাথে /usr/xpg4/bin/tr, tr -d a-zকাজ tr -d '[a-z]'করে কিন্তু মুছে [না বা না ]
স্টাফেন চেজেলাস

1
/usr/xpg4/bin/tr -d '[a-z]'মুছে ফেলা হচ্ছে [না ]বা দৃশ্যত সোলারিস ১১-তে স্থির করা হয়েছিল
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.