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


143

নিম্নলিখিত কোডটিতে কী ভুল?

name='$filename | cut -f1 -d'.''

যেমনটি হ'ল আমি আক্ষরিক স্ট্রিংটি $filename | cut -f1 -d'.'পাই তবে আমি উদ্ধৃতিগুলি সরিয়ে ফেললে আমি কিছুই পাই না। এদিকে, টাইপিং

"test.exe" | cut -f1 -d'.'

একটি শেল আমাকে আমার আউটপুট দেয় test,। আমি ইতিমধ্যে জানি $filenameসঠিক মান নির্ধারিত হয়েছে। আমি যা করতে চাই তা হল কোনও এক্সটেনশন ছাড়াই ফাইলের একটি ভেরিয়েবলকে বরাদ্দ করা।


6
basename $filename .exeএকই জিনিস করতে হবে। এটি ধরে নেওয়া হচ্ছে আপনি সর্বদা জানেন আপনি কী এক্সটেনশনটি সরাতে চান know
এমপি

6
@mpe, আপনি কি বলতে চান basename "$filename" .exe। অন্যথায় স্পেস সহ ফাইলের নামগুলি খারাপ খবর হবে।
চার্লস ডাফি

উত্তর:


113

আপনি যখন স্ক্রিপ্ট / কমান্ডে কোনও আদেশ প্রয়োগ করতে চান তখন আপনার কমান্ড প্রতিস্থাপন সিনট্যাক্স ব্যবহার করা উচিত $(command)

সুতরাং আপনার লাইন হবে

name=$(echo "$filename" | cut -f 1 -d '.')

কোড ব্যাখ্যা:

  1. echoভেরিয়েবলের মান পান $filenameএবং এটি স্ট্যান্ডার্ড আউটপুটে প্রেরণ করুন
  2. তারপরে আমরা আউটপুটটি ধরে নিয়ে cutকমান্ডটিতে পাইপ করব
  3. cutব্যবহার করবে। বিভাগগুলিতে স্ট্রিং কাটানোর জন্য ডিলিমিটার হিসাবে (বিভাজক হিসাবেও পরিচিত) এবং -fআমরা কোন বিভাগটি আউটপুট রাখতে চাই তা নির্বাচন করে
  4. তারপরে $()কমান্ড সাবস্টিটিউশন আউটপুট পাবে এবং এর মান ফিরিয়ে দেবে
  5. প্রত্যাশিত মানটি ভেরিয়েবলের জন্য বরাদ্দ করা হবে name

দ্রষ্টব্য যে এটি প্রথম সময়ের পর্যন্ত ভেরিয়েবলের অংশ দেয় .:

$ filename=hello.world
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello.hello.hello
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello
$ echo "$filename" | cut -f 1 -d '.'
hello

ধন্যবাদ। আমি এও লক্ষ্য করেছি যে আমার ইকো কমান্ড ব্যবহার করা দরকার। নাম =echo $filename | cut -f1 -d'.'
মিমিকোকোটপাস

17
ব্যসটিকগুলি পসিক্স দ্বারা অবহিত করা হয়, $()পছন্দ করা হয়।
jordanm

3
কয়েকটি চরিত্রটি পেতে ফোর্কিং এবং পাইপিং কল্পনা করার মতো সবচেয়ে খারাপ সমাধান।
জেনস

39
এই উত্তরের সমস্যাটি হ'ল এটি অনুমান করে যে ইনপুট স্ট্রিংয়ের কেবলমাত্র একটি বিন্দু রয়েছে ... নীচের চ্যান্টারের আরও অনেক ভাল সমাধান রয়েছে ... নাম = $ {ফাইলের নাম% * *}
স্কট স্টেনস্ল্যান্ড

4
এই উত্তরটি প্রাথমিকদের বৈশিষ্ট্য এবং এটি ছড়িয়ে দেওয়া উচিত নয়। চেপনারের উত্তর দ্বারা বর্ণিত বিল্টিন মেকানিজমটি ব্যবহার করুন
স্নাতক

257

আপনি প্যারামিটার সম্প্রসারণও ব্যবহার করতে পারেন:

$ filename=foo.txt
$ echo "${filename%.*}"
foo

6
কমান্ডটির ব্যাখ্যা এখানে: gnu.org/software/bash/manual/html_node/…
কার্লোস

1
এবং এখানে আমি ব্যবহার করতে চলেছিলাম echo -n "This.File.Has.Periods.In.It.txt" | awk -F. '{$NF=""; print $0}' | tr ' ' '.' | rev | cut -c 2- | rev। ধন্যবাদ।
ব্যবহারকারী 208145

1
এটি কি একাধিক এক্সটেনশানযুক্ত ফাইলগুলির সাথে কাজ করে image.png.gz?
হককার 65

11
%.*শুধুমাত্র শেষ এক্সটেনশন সরিয়ে ফেলবে; আপনি যদি সমস্ত এক্সটেনশান মুছে ফেলতে চান তবে ব্যবহার করুন %%.*
চিপনার

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

117

আপনি যদি এক্সটেনশনটি জানেন তবে আপনি বেস নামটি ব্যবহার করতে পারেন

$ basename /home/jsmith/base.wiki .wiki
base

আমি কীভাবে সরাতে পারি .wikiএবং শেষ করতে পারি /home/jsmith/base?
গ্যাব্রিয়েল স্ট্যাপলস

আপডেট: উত্তর: স্ট্যাকওভারফ্লো . com/a/32584935/4561887 দেখুন । পুরোপুরি কাজ করে!
গ্যাব্রিয়েল স্ট্যাপলস

20

যদি আপনার ফাইলের নামটিতে একটি বিন্দু থাকে (এক্সটেনশনের একটি বাদে) তবে এটি ব্যবহার করুন:

echo $filename | rev | cut -f 2- -d '.' | rev

1
আমি মাঝের রেভকে ভুলে গিয়েছিলাম, কিন্তু একবার এটি দেখেছি, এটি দুর্দান্ত ছিল!
সুপ্রিম পূবা

-sদেওয়া বিকল্পের সাথে এটি আরও ভাল cut, যাতে যখনই ফাইলের নামটিতে কোনও বিন্দু না থাকে এটি খালি স্ট্রিংটি দেয়।
Hibou57

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

20
file1=/tmp/main.one.two.sh
t=$(basename "$file1")                        # output is main.one.two.sh
name=$(echo "$file1" | sed -e 's/\.[^.]*$//') # output is /tmp/main.one.two
name=$(echo "$t" | sed -e 's/\.[^.]*$//')     # output is main.one.two

আপনি যা চান ব্যবহার করুন। এখানে আমি ধরে নিই যে .পাঠ্যের পরে সর্বশেষ (ডট) এক্সটেনশন।


6
#!/bin/bash
file=/tmp/foo.bar.gz
echo $file ${file%.*}

আউটপুট:

/tmp/foo.bar.gz /tmp/foo.bar

মনে রাখবেন যে শুধুমাত্র শেষ এক্সটেনশন সরানো হয়েছে is


3

আমার সুপারিশটি ব্যবহার করা basename
এটি উবুন্টুতে ডিফল্টরূপে, ভিজ্যুয়ালি সহজ কোড এবং বেশিরভাগ ক্ষেত্রে মোকাবেলা করা হয়।

শূন্যস্থান এবং মাল্টি-ডট / সাব-এক্সটেনশন মোকাবেলার জন্য এখানে কয়েকটি উপ-কেস রয়েছে:

pathfile="../space fld/space -file.tar.gz"
echo ${pathfile//+(*\/|.*)}

এটি সাধারণত প্রথম থেকেই প্রসার থেকে মুক্তি পায় .তবে আমাদের ..পথে ব্যর্থ হয়

echo **"$(basename "${pathfile%.*}")"**  
space -file.tar     # I believe we needed exatly that

এখানে একটি গুরুত্বপূর্ণ নোট:

আমি স্পেসগুলি মোকাবেলায় ডাবল কোটসের ভিতরে ডাবল কোট ব্যবহার করেছি। একক উদ্ধৃতি tex টেক্সট করার কারণে পাস হবে না $ বাশ অস্বাভাবিক এবং প্রসারণের কারণে "দ্বিতীয়" প্রথম "উদ্ধৃতি" পড়ে।

তবে, আপনার এখনও চিন্তা করা দরকার .hidden_files

hidden="~/.bashrc"
echo "$(basename "${hidden%.*}")"  # will produce "~" !!!  

প্রত্যাশিত ফলাফল নয়। এটি ব্যবহারে ঘটানোর জন্য $HOMEবা /home/user_path/
আবার ব্যাশটি "অস্বাভাবিক" এবং "~" প্রসারিত করবেন না (ব্যাশের বাশপিটফলগুলি অনুসন্ধান করুন)

hidden2="$HOME/.bashrc" ;  echo '$(basename "${pathfile%.*}")'

1
#!/bin/bash
filename=program.c
name=$(basename "$filename" .c)
echo "$name"

আউটপুট:

program

৫ বছর আগে স্টিভেন পেনি যে উত্তর দিয়েছিলেন তা থেকে এটি কীভাবে আলাদা?
gniourf_gniourf

1

চ্যাপার উত্তরের মন্তব্যে হককার 65 দ্বারা নির্দেশিত হিসাবে, সর্বাধিক ভোট দেওয়া সমাধানটি একাধিক এক্সটেনশান (যেমন ফাইলের নাম.আর্ট্রিজেড), না বাকী পথের বিন্দু (যেমন এই.পথ / সহ) যত্ন করে না .dots / in.path.name)। একটি সম্ভাব্য সমাধান হ'ল:

a=this.path/with.dots/in.path.name/filename.tar.gz
echo $(dirname $a)/$(basename $a | cut -d. -f1)

এই একটি "tar.gz" স্ট্রিপ অক্ষর নির্বাচন করে ফাইল নেমে কোনও বিন্দুর আগে পথ গণনা করছে না। একটি সম্ভবত এক্সটেনশনগুলি সেভাবে ফেলাতে চান না।
ফ্রটজ

0

আপনার কোড নিয়ে দুটি সমস্যা:

  1. আপনি ভেরিয়েবলটিতে সঞ্চয় করতে চান এমন স্ট্রিং তৈরি করে এমন কমান্ডগুলি ঘিরে আপনি `(ব্যাক টিক) পরিবর্তে '(টিক) ব্যবহার করেছেন।
  2. আপনি "কাটা" কমান্ডের পাইপে "ভেরিয়েবল" ফাইলনাম "" প্রতিধ্বনি "করেন নি।

আমি আপনার কোডটি "নাম =` প্রতিধ্বনি $ ফাইলের নাম | কাট -f 1 -d 'এ পরিবর্তন করব।' `", নীচে প্রদর্শিত হিসাবে (আবার, নামের পরিবর্তনশীল সংজ্ঞাটি ঘিরে পিছনের টিকগুলি লক্ষ্য করুন):

$> filename=foo.txt
$> echo $filename
foo.txt
$> name=`echo $filename | cut -f1 -d'.'`
$> echo $name
foo
$> 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.