আমি কীভাবে ফাইলের প্রত্যয় এবং পাথ অংশটি ব্যাশের কোনও পাথ স্ট্রিং থেকে সরিয়ে দেব?


396

একটি স্ট্রিং ফাইল পাথ দেওয়া যেমন /foo/fizzbuzz.bar, আমি কীভাবে fizzbuzzস্ট্রিংয়ের অংশটি বের করতে ব্যাশ ব্যবহার করব ?


Informations আপনি খুঁজে পেতে পারেন ব্যাশ ম্যানুয়াল জন্য তাকান ${parameter%word}এবং ${parameter%%word}অংশ ম্যাচিং অধ্যায় trailing হবে।
1ac0

উত্তর:


573

বাশে # এবং% অপারেটরদের সাথে এটি কীভাবে করা যায় তা এখানে।

$ x="/foo/fizzbuzz.bar"
$ y=${x%.bar}
$ echo ${y##*/}
fizzbuzz

${x%.bar}${x%.*}বিন্দুর ${x%%.*}পরে সমস্ত কিছু মুছে ফেলা বা প্রথম বিন্দুর পরে সমস্ত কিছু সরিয়ে ফেলাও হতে পারে ।

উদাহরণ:

$ x="/foo/fizzbuzz.bar.quux"
$ y=${x%.*}
$ echo $y
/foo/fizzbuzz.bar
$ y=${x%%.*}
$ echo $y
/foo/fizzbuzz

ডকুমেন্টেশন বাশ ম্যানুয়ালটিতে পাওয়া যাবে । দেখুন ${parameter%word}এবং ${parameter%%word}অংশ ম্যাচিং অধ্যায় trailing।


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

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

7
যাকে} {x% .bar} বলা হয়? আমি এটি সম্পর্কে আরও জানতে চাই।
তুলসী

14
@ বাসিল: প্যারামিটার সম্প্রসারণ। কনসোলে "ম্যান বাশ" টাইপ করুন এবং তারপরে "/ প্যারামিটার সম্প্রসারণ" টাইপ করুন
জ্যান লিনাক্স

1
আমি অনুমান করি যে 'ম্যান বাশ' ব্যাখ্যাটি বোধগম্য হয় যদি আপনি ইতিমধ্যে এটি কী করে তা জানেন বা যদি আপনি নিজেরাই চেষ্টা করে যান। এটি প্রায় গিট রেফারেন্স হিসাবে খারাপ। আমি পরিবর্তে এটি গুগল করব।
ট্রিপলবিগ

225

বেসনাম কমান্ডটি দেখুন:

NAME="$(basename /foo/fizzbuzz.bar .bar)"

11
সম্ভবত সমস্ত প্রস্তাবিত সমাধানগুলির মধ্যে সবচেয়ে সহজ ... যদিও আমি ব্যাকটিকের পরিবর্তে $ (...) ব্যবহার করব।
মাইকেল জনসন

6
সর্বাধিক সহজ তবে নির্ভরতা যুক্ত করুন (বিশাল বা অদ্ভুত নয়, আমি স্বীকার করি)। এটি প্রত্যয়টিও জানতে হবে।
ভিঙ্কো ভার্সালোভিক

এবং শেষ থেকে যে কোনও কিছু সরাতে ব্যবহার করা যেতে পারে, মূলত এটি শেষ থেকে কেবল একটি স্ট্রিং অপসারণ করে।
স্মার

2
সমস্যা হ'ল সময় হিট। আমি খালি এই আলোচনার জন্য প্রশ্নটি অনুসন্ধানের পরে বেসনাম ব্যবহার করে 800 টি ফাইল প্রক্রিয়া করতে 5 মিনিট সময় নেওয়ার পরেছি। উপরের রেজেক্স পদ্ধতিটি ব্যবহার করে সময়টি প্রায় 7 সেকেন্ডে কমিয়ে আনা হয়েছিল। যদিও এই উত্তরটি প্রোগ্রামারের পক্ষে সঞ্চালন করা আরও সহজ, সময় হিট কেবল খুব বেশি। এতে কয়েক হাজার ফাইল সহ একটি ফোল্ডারটি কল্পনা করুন! আমার এ জাতীয় কিছু ফোল্ডার রয়েছে।
xizdaqrian

@ xizdaqrian এটি একেবারেই ভুল। এটি একটি সাধারণ প্রোগ্রাম, যা ফিরে আসতে আধ সেকেন্ড সময় নেওয়া উচিত নয়। আমি স্রেফ / হোম / আমাকে / দেব-নাম "* .py" .py -exec বেসনাম {} \; এবং এটি 1500 ফাইলের জন্য 1 সেকেন্ডে এক্সটেনশন এবং ডিরেক্টরিটি ছিনিয়ে নিয়েছে।
লাসলো ট্র্রেসকাই

40

খাঁটি বাশ, দুটি পৃথক ক্রিয়াকলাপে সম্পন্ন:

  1. কোনও পাথ-স্ট্রিং থেকে পাথটি সরান:

    path=/foo/bar/bim/baz/file.gif
    
    file=${path##*/}  
    #$file is now 'file.gif'
  2. কোনও পাথ-স্ট্রিং থেকে এক্সটেনশনটি সরান:

    base=${file%.*}
    #${base} is now 'file'.

18

এটি অর্জনের জন্য আমি বেস ব্যবহার করে নিম্নলিখিত ব্যবহার করেছি:

for file in *; do
    ext=${file##*.}
    fname=`basename $file $ext`

    # Do things with $fname
done;

এটির জন্য ফাইল এক্সটেনশনের কোনও পূর্বের জ্ঞান প্রয়োজন হয় না এবং এটির একটি ফাইলের নাম রয়েছে যা তার ফাইলনেটে বিন্দু রয়েছে (এটির এক্সটেনশনের সামনে); এটির জন্য প্রোগ্রামটি প্রয়োজন basenameতবে এটি জিএনইউ কোর্টিলগুলির একটি অংশ তাই এটি কোনও ডিস্ট্রো দিয়ে শিপিং করা উচিত।


1
দুর্দান্ত উত্তর! খুব পরিষ্কার উপায়ে এক্সটেনশনটি সরিয়ে দেয় তবে এটি সরিয়ে দেয় না। ফাইল নাম শেষে।
মেট্রিক্স

3
@ মেট্রিক্স কেবল "যোগ করুন"। $ ext এর আগে, অর্থাত: fname=`basename $file .$ext`
কার্লোস ট্রোনকসো

13

খাঁটি বাশ উপায়:

~$ x="/foo/bar/fizzbuzz.bar.quux.zoom"; 
~$ y=${x/\/*\//}; 
~$ echo ${y/.*/}; 
fizzbuzz

এই কার্যকারিতাটি "প্যারামিটার সম্প্রসারণ" এর অধীনে ম্যান ব্যাশে ব্যাখ্যা করা হয়েছে। অ-বাশ পদ্ধতিতে প্রচুর পরিমাণে: ওকেড, পার্ল, সেড এবং আরও।

সম্পাদনা করুন: ফাইলের মধ্যে বিন্দু সাথে কাজ করে প্রত্যয় ও প্রত্যয় (এক্সটেনশন) জানতে হবে না, কিন্তু না এ বিন্দু সঙ্গে কাজ নাম নিজেই।


11

বেসনেম এবং ডেরনাম ফাংশনগুলি আপনার পরে যা রয়েছে:

mystring=/foo/fizzbuzz.bar
echo basename: $(basename "${mystring}")
echo basename + remove .bar: $(basename "${mystring}" .bar)
echo dirname: $(dirname "${mystring}")

আউটপুট রয়েছে:

basename: fizzbuzz.bar
basename + remove .bar: fizzbuzz
dirname: /foo

1
এখানে উদ্ধৃত ঠিক করতে সহায়ক হবে - হয়তো মাধ্যমে এই চালানোর shellcheck.net সঙ্গে mystring=$1বদলে বর্তমান ধ্রুবক রয়েছে যার মান (যা একাধিকবার সতর্ক দমন করবে স্পেস / উল্লিখিত glob অক্ষর / ইত্যাদি ধারণ করে না নির্দিষ্ট হচ্ছে), এবং ঠিকানা বিষয় এটা খুঁজে বের করে?
চার্লস ডাফি

ওয়েল, আমি st মাইস্ট্রিংয়ের উদ্ধৃতি চিহ্নগুলি সমর্থন করার জন্য কিছু উপযুক্ত পরিবর্তন করেছি। খুশী এটি অনেক দিন আগে আমি এটি লিখেছিলাম :)
জেরুব

ফলাফলগুলি উদ্ধৃত করার জন্য আরও উন্নতি হবে: echo "basename: $(basename "$mystring")"- mystring='/foo/*'আপনি যদি *বর্তমান ডিরেক্টরিতে ফাইলগুলির একটি তালিকা সমাপ্তির পরে প্রতিস্থাপন না করেন তবে এইভাবে basename
চার্লস ডাফি

6

basenameঅনুমান করে ব্যবহার করে যে আপনি ফাইল এক্সটেনশন কি জানেন, তাই না?

এবং আমি বিশ্বাস করি যে বিভিন্ন নিয়মিত প্রকাশের পরামর্শগুলি একের অধিক "" ফাইলের নামের সাথে মান দেয় না। "

নিম্নলিখিতগুলি ডাবল ডটগুলি সহ্য করতে পারে বলে মনে হচ্ছে। ওহ, এবং ফাইলের নামগুলি যাতে একটি "/" থাকে (কেবল কিকের জন্য)

পাসক্যালকে প্যারাফ্রেস করতে, "দুঃখিত এই স্ক্রিপ্টটি এত দীর্ঘ।


  #!/usr/bin/perl
  $fullname = $ARGV[0];
  ($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
  ($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
  print $basename . "\n";
 

1
এটি দুর্দান্ত এবং
গৌরব জৈন

4

এই উত্তরে ব্যবহৃত পসিক্স কনফর্মেন্ট সিনট্যাক্স ছাড়াও ,

basename string [suffix]

হিসাবে হিসাবে

basename /foo/fizzbuzz.bar .bar

জিএনইউbasename আরও একটি বাক্য গঠন সমর্থন করে:

basename -s .bar /foo/fizzbuzz.bar

একই ফলাফল সঙ্গে। পার্থক্য এবং সুবিধাটি -sবোঝায় যে -aএকাধিক যুক্তি সমর্থন করে:

$ basename -s .bar /foo/fizzbuzz.bar /baz/foobar.bar
fizzbuzz
foobar

-zঅপশনটি ব্যবহার করে NUL বাইটের সাহায্যে আউটপুট আলাদা করে এটিকে ফাইলের নাম-সুরক্ষিত করা যায় , উদাহরণস্বরূপ, এই ফাইলগুলির মধ্যে ফাঁকা, নিউলাইনস এবং গ্লোব অক্ষর রয়েছে (এর দ্বারা উদ্ধৃত ls):

$ ls has*
'has'$'\n''newline.bar'  'has space.bar'  'has*.bar'

একটি অ্যারেতে পড়া:

$ readarray -d $'\0' arr < <(basename -zs .bar has*)
$ declare -p arr
declare -a arr=([0]=$'has\nnewline' [1]="has space" [2]="has*")

readarray -d4.4 বা আরও বাশ প্রয়োজন। পুরানো সংস্করণগুলির জন্য, আমাদের লুপ করতে হবে:

while IFS= read -r -d '' fname; do arr+=("$fname"); done < <(basename -zs .bar has*)

এছাড়াও, উপস্থিত প্রত্যয়টি যদি উপস্থিত থাকে তবে আউটপুটগুলিতে সরানো হয় (এবং অন্যথায় উপেক্ষা করা হবে)।
aksh1618


3

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

echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g'

যা আপনাকে আউটপুট দেবে

fizzbuzz


যদিও এটি মূল প্রশ্নের উত্তর, তবে এই কমান্ডটি কার্যকর যখন আমার কাছে কোনও ফাইলের পাতাগুলির পাতায় মুদ্রণ করতে বেস নামগুলি বের করার জন্য একটি ফাইল থাকে lines
সাংচেওল চোই

2

প্রস্তাবিত পার্ল সমাধান থেকে সাবধান থাকুন: এটি প্রথম বিন্দুর পরে কোনও কিছু সরিয়ে দেয়।

$ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}'
some

আপনি যদি পার্ল দিয়ে এটি করতে চান তবে এটি কাজ করে:

$ echo some.file.with.dots | perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'
some.file.with

তবে আপনি যদি ব্যাশ ব্যবহার করছেন তবে এর সমাধানগুলি y=${x%.*}(বা basename "$x" .extআপনি যদি এক্সটেনশনটি জানেন তবে) অনেক সহজ।


1

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


1

পুরো পাথ ছাড়াই ফাইলের নাম পেতে দ্বিতীয়-শীর্ষ-রেট করা উত্তরের সাথে শীর্ষ-রেট করা উত্তরের সংমিশ্রণ:

$ x="/foo/fizzbuzz.bar.quux"
$ y=(`basename ${x%%.*}`)
$ echo $y
fizzbuzz

আপনি এখানে একটি অ্যারে ব্যবহার করছেন কেন? এছাড়াও, কেন বেসামাল ব্যবহার আদৌ?
কোডফোরস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.