ব্যাশে ডিরেক্টরি এবং আপেক্ষিক পাথগুলি খুঁজতে আমি কীভাবে $ 0 ভেরিয়েবলকে বিভক্ত করব?


10

$ 0 ভেরিয়েবলটিতে স্ক্রিপ্টের পথের তথ্য রয়েছে।

  • আমি কীভাবে পাথের তথ্যটিকে পরম পথে পরিবর্তন করতে পারি? মানে কীভাবে process,।, .. বা অনুরূপ প্রক্রিয়া করা যায়?
  • আমি কীভাবে পাথ তথ্যকে ডিরেক্টরি এবং ফাইলের নামে বিভক্ত করতে পারি?

আমি এর জন্য পাইথন / পার্ল ব্যবহার করতে পারি, তবে আমি যদি সম্ভব হয় তবে ব্যাশ ব্যবহার করতে চাই।


আপনি কি অর্জন করার চেষ্টা করছেন? BTW। b / foo.sh এর সাথে একটি স্ক্রিপ্ট কল করা আমার বাশ সংস্করণ (জিএনইউ ব্যাশ, সংস্করণ 4.1.5 (2) -রেলেজ- (
x86_64-

উত্তর:


17

আপনার মতো জিনিসগুলি প্রক্রিয়া করার দরকার ~নেই, শেলটি এটি আপনার জন্য করে। এজন্য আপনি ~/filenameযে কোনও স্ক্রিপ্ট বা প্রোগ্রামে যেতে পারেন এবং এটি কাজ করে - এই সমস্ত প্রোগ্রাম ~নিজেরাই হ্যান্ডেল করে না , আপনার শেল আর্গুমেন্টকে রূপান্তরিত করে /home/username/filenameএবং পরিবর্তে প্রোগ্রামটিতে এটি প্রেরণ করে:

$ echo ~/filename
/home/mrozekma/filename

আপনার যদি কোনও ক্যানোনিকাল ফাইল নাম প্রয়োজন হয় (যার মধ্যে এমন কিছু অন্তর্ভুক্ত না থাকে ..), ব্যবহার করুন realpath(ধন্যবাদ নীল ):

$ realpath ~/../filename
/home/filename

ডিরেক্টরিটিকে নাম এবং ফাইলের নামে বিভক্ত করার জন্য, ব্যবহার করুন dirnameএবং basename:

$ dirname /foo/bar/baz
/foo/bar

$ basename /foo/bar/baz
baz

আমি মনে করি আপনি রিয়েলপথ বলতে চাইছেন, রিডলিঙ্ক নয়। রিডলিঙ্কটি সাধারণ পরিস্থিতিতে কাজ করবে না, অর্থাত্ লিঙ্কটি যখন কোনও আপেক্ষিক পথ ব্যবহার করে এবং আপনি লিঙ্কটির মতো দির তেমন হন না।
নিল মেহেজ

@ নীল realpathআরও ভাল, তবে readlinkআমি চেষ্টা করে দেখলে তা মনে হয়; আপনি এটির ব্যর্থতার উদাহরণ জানেন?
মাইকেল মরোজেক

1
cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar। এটি ফিরে আসে fooএবং realpathফিরে আসে /tmp/foo, যা আপনি চান।
নিল মেহেজ

1
@ নীল, @ মিশেল: readlink -f(নোট -f) প্রায় সমান realpath, এবং এটি আরও বহনযোগ্য: readlink -fজিএনইউ কোর্টিলগুলিতে এবং কয়েকটি অন্যান্য সিস্টেমেও রয়েছে; realpathপৃথকভাবে প্যাকেজ করা হয়েছে এবং ইনস্টল করা যাবে না (যেমন উবুন্টু 10.04 বা ডেবিয়ান লেনিতে কেবল 5 টি সাধারণ প্যাকেজ নির্ভর করে)।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

@ গিলস: ভাল পয়েন্ট রিয়েলপথ -f সম্পর্কে অনুস্মারকটির জন্য ধন্যবাদ।
নিল মেহেহে

5

মাইকের দ্বারা বর্ণিত ডাইরনাম এবং বেসনামটি ব্যবহার করা আপনি যা চান তা পাওয়ার সবচেয়ে নিরাপদ উপায় হওয়া উচিত।

যাইহোক আপনি যদি সত্যিই "বাশ কেবলমাত্র সরঞ্জাম" দিয়ে এটি করতে চান তবে আপনি প্যারামিটার বিকল্প ব্যবহার করতে পারেন:

echo `basename $PWD`        # Basename of current working directory.
echo "${PWD##*/}"           # Basename of current working directory.
echo
echo `basename $0`          # Name of script.
echo $0                     # Name of script.
echo "${0##*/}"             # Name of script.
echo
filename=test.data
echo "${filename##*.}"      # data
                            # Extension of filename.

এই উদাহরণটি সরাসরি অ্যাডভান্সড ব্যাশ স্ক্রিপ্টিং গাইড থেকে নেওয়া হয়েছে যা দেখার মতো।

ব্যাখ্যাটি বেশ সহজ:

$ {var # প্যাটার্ন} $ var এর সামনের প্রান্তের সাথে মেলে এমন $ প্যাটার্নের সবচেয়ে সংক্ষিপ্ত অংশ $ var থেকে} var থেকে সরান। $ {var ## প্যাটার্ন} $ var এর সম্মুখ প্রান্তের সাথে মেলে এমন $ প্যাটার্নের দীর্ঘতম অংশ $ var থেকে সরান।

কিছু রেজেক্সের মতো #বা ##কোনও ধরণের লোভী / অ-লোভী সংশোধক হিসাবে প্যাটার্নটি দেখুন ।

আপনাকে যদি কোনও পথের অংশের আরও কিছু জটিল উত্তোলন করতে হয় তবে এটি কার্যকর হতে পারে।


5
ব্যবহার করার সময় ${...##...}এবং বন্ধুদের পরিবর্তে সাবধান থাকুন dirnameএবং basenameতারা সব ক্ষেত্রেই কাজ করে না। উদাহরণস্বরূপ উভয় ${0##*/}এবং ${0%/*}একই হিসাবে প্রসারিত $0যদি $0একটি থাকে না /
গিলস 'দুষ্ট হওয়া বন্ধ করুন'

@ গিলস আমি বুঝতে পারি যে এর কেন ${0%/*}ভাল বিকল্প নয় dirname। তবে এর ${0##*/}পরিবর্তে ব্যবহারে দোষ কী basename?
টক্সালোট

@toxalot এই এক জন্য, একমাত্র সমস্যা যখন $0একটি trailing সঙ্গে একটি ডিরেক্টরির নাম /। তবে আমি আমার পরামর্শের জন্য আফসোস করছি কারণ এর dirnameচেয়ে ভাল আর কিছু করে না।
গিলস'স 14-8

2

realpath হ'ল একটি আদেশ যা আপনাকে সত্যিকারের পথ (অপসারণ .. এবং প্রতীকী লিঙ্কগুলি ইত্যাদি) বলে দেয়

এটি ফ্রিবিএসডি-র সাথে মানক। এই আলোচনা অনুসারে এটি লিনাক্সের জন্যও উপলব্ধ:

http://www.unix.com/shell-programming-scripting/89294-geting-real-path.html

এই আলোচনাটিও একটি ব্যাশ সমাধান দেয়:

$ bash -c "cd /foo/../bar/ ; pwd"

1
ঠিক ঠিক, এর মতো কিছু সাধারণত কাজ করে: এমওয়াইডিআর = "$ (সিডি ir (dirname" $ ​​0 "); পিডব্লুডে)"
কেভিন কেন্টু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.