বাশ-এ একটি ফাইল পাথ আর্গুমেন্টে সর্বশেষ নাম / ফাইলের নাম পান


228

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

উদাহরণস্বরূপ, যদি আমি প্রকল্পের "উদাহরণ" এর সাথে কোনও এসভিএন প্রতিশ্রুতিবদ্ধ করি তবে আমার স্ক্রিপ্টটি তার প্রথম যুক্তি হিসাবে "/ usr / স্থানীয় / এসএনএন / রেপোস / উদাহরণ" পেয়েছে। স্ট্রিংয়ের শেষে আমার "উদাহরণস্বরূপ" পাওয়া দরকার এবং এরপরে এটি অন্য স্ট্রিংয়ের সাথে একত্রীকরণ করতে হবে যাতে আমি "/ সার্ভার / রুট / উদাহরণ" এ চেকআউট করতে পারি এবং ততক্ষনে পরিবর্তনগুলি সরাসরি দেখতে পারি।

উত্তর:


344

basename কোনও পাথের ডিরেক্টরি উপসর্গটি সরিয়ে দেয়:

$ basename /usr/local/svn/repos/example
example
$ echo "/server/root/$(basename /usr/local/svn/repos/example)"
/server/root/example

2
বেসনেম অবশ্যই আমি যা খুঁজছি কিভাবে একটি চলক মধ্যে সংরক্ষণ করা একটি আর্গুমেন্ট এর বেস নাম পেতে পারেন? উদাহরণস্বরূপSUBDIR="/path/to/whatever/$(basename $1)"
টিজে এল

5
@ tj111: শব্দ শুনে মনে হচ্ছে নেই $1, অথবা $1খালি
হেলায়

দুর্ভাগ্যক্রমে, আপনি যদি আদেশগুলি মোড়ানো করেন তবে বেসনামটি ভাল ধারণা নয়। কিছু মনে রাখবেন
dtc

98

নীচের পদ্ধতির কোনও পথের কোনও পথ পেতে ব্যবহার করা যেতে পারে:

some_path=a/b/c
echo $(basename $some_path)
echo $(basename $(dirname $some_path))
echo $(basename $(dirname $(dirname $some_path)))

আউটপুট:

c
b
a

1
ফাঁকা জায়গাগুলির সাথে কাজ করে না ... আপনি উদ্ধৃতি দিয়ে এটি কাটিয়ে উঠতে পারেন ... যা কোনওরকম কাজ করেecho "$(basename "$(dirname "$pathname")")"
রায় ফস

75

বাহ্যিককে বাহ্যিক কল না করেই কোনও পথের শেষ অংশটি পেতে পারে basename:

subdir="/path/to/whatever/${1##*/}"

2
আমার ম্যাক-তে, স্ট্রিং নোটেশন ব্যবহার করা আপনার ক্ষেত্রে কয়েক হাজার ফাইলের জন্য কিছু তুচ্ছ কিছু করছেন এমন ক্ষেত্রে ডাইরনাম / বেসনামের চেয়ে তাত্পর্য ক্রমের চেয়ে আরও দ্রুত।
জর্জ

1
d=/home/me/somefolder;subdir="/$d/${1##*/}"প্রত্যাশিত কাজগুলি ব্যবহার করে //home/me/somefolder//$ d আসলে লুপ থেকে আসে এমন কিছু দিয়ে শেষ করেছি । for d in $(find $SOMEFOLDER -maxdepth 1 -type d);subdir=$(basename $d)
বাটল বাটকাস

1
@ বাটলবাটকাস: আপনার আউটপুট ( পুনর্বার ভাল) এর পুনরাবৃত্তি করার whileপরিবর্তে ব্যবহার করা উচিত বা গ্লোব্বিং ব্যবহার করা উচিত:forfindfind -print0 | xargs -0for d in $SOMEFOLDER/*/ (চূড়ান্ত স্ল্যাশ কাজ করে -type d- আপনি **যদি পুনরাবৃত্তির জন্য বাশ 4 তে ব্যবহার করতে পারেন shopt -s globstarতবে "আর্গুমেন্টের তালিকা খুব দীর্ঘ" বার্তাটি সম্ভব). নোট করুন যে ${1}কমান্ডের অংশটি কোনও স্ক্রিপ্ট বা ফাংশনের প্রথম যুক্তিকে উপস্থাপন করে। আপনার প্রয়োজন হতে পারে ${d##*/}বা অন্য কোনও পরিবর্তনশীল বা যুক্তির স্পেসিফিকেশন ব্যবহার করতে হবে বা এটি নিশ্চিত করতে হবে যে কোনও আর্গুমেন্টটি পাস হচ্ছে$1
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

2
@ ডেনিস উইলিয়ামসন ভাগ করে নেওয়ার জন্য অনেক ধন্যবাদভবিষ্যতের যে কোনও পাঠক যারা ভাবছেন যে এটি কেন কাজ করছে না বা আমি এখানে কেবল বোকা 😂 উপরের উত্তর ধরে যা $1ধারণ করে the path from which last component is to be taken out। আমি সেই অংশটি মিস করেছি। আমার ব্যবহারের কেস: target_path='/home/user/dir1/dir2/dir3/'; target_path="${target_path%/}"; last_component=${target_path##*/}; echo $last_component- ওয়ার্কস 😉
বিনয় বিশশ

2
কীভাবে এবং কীভাবে ${1##*/} কাজ করে তার ব্যাখ্যার জন্য এখানে দেখুন : unix.stackexchange.com/a/171786/15070
ম্যাথু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.