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


169

আমি বশে একটি নাইট বিল্ড স্ক্রিপ্ট লিখছি।
একটি সামান্য ছিনতাই ব্যতীত সবকিছু ঠিকঠাক এবং জঘন্য:


#!/bin/bash

for file in "$PATH_TO_SOMEWHERE"; do
      if [ -d $file ]
      then
              # do something directory-ish
      else
              if [ "$file" == "*.txt" ]       #  this is the snag
              then
                     # do something txt-ish
              fi
      fi
done;

আমার সমস্যাটি ফাইলের এক্সটেনশনটি নির্ধারণ করে তারপরে কাজ করে। আমি জানি সমস্যাটি যদি ই-স্টেটমেন্টে থাকে তবে একটি টেক্সট ফাইলের পরীক্ষা করা।

কোনও ফাইলের .txt প্রত্যয় আছে কিনা তা আমি কীভাবে নির্ধারণ করতে পারি?


এটির নামে একটি স্থান সহ আপনার যদি কোনও ফাইল থাকে তবে এটি ভঙ্গ হবে।
jfg956

পলের উত্তর ছাড়াও, আপনি ব্যবহার করতে পারেন $(dirname $PATH_TO_SOMEWHERE)এবং $(basename $PATH_TO_SOMEWHERE)ফোল্ডার এবং ডিরেক্টরিতে বিভক্ত করতে এবং ডিরেক্টরি-ইশ এবং ফাইল-ইশ কিছু করতে পারেন
ম্যাকপ্প্পার

উত্তর:


248

আমার মনে হয় আপনি "ফাইলের শেষ চারটি অক্ষরের সমান .txt?" যদি তা হয় তবে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন:

if [ ${file: -4} == ".txt" ]

নোট করুন যে এর মধ্যে file:এবং -4প্রয়োজনীয় স্থানটি , যেমন ': -' পরিবর্তক অর্থ ভিন্ন কিছু।


1
সেই লক্ষ্যে, আপনি উইন্ডোজ মেশিনেও কমান্ড ডট কমের নাম পরিবর্তন করতে পারেন।
হোমটিস্ট

9
আপনি যদি কোনও অসমতা নির্দিষ্ট করতে চান তবে অতিরিক্ত বন্ধনী অন্তর্ভুক্ত করতে মনে রাখবেন: যদি [[$ {ফাইল: -4}! = ".Txt"]]
রাম রামননি

4
@ রামরাজমনি কেন [[বৈষম্যের পরীক্ষার সময় ব্যবহার করা প্রয়োজন?
PesaThe

আমি উল্লেখ করতে চেয়েছিলাম যে কোলনের পরে স্থানটি গুরুত্বপূর্ণ। ${var:-4}হিসাবে একই নয় ${var: -4}; প্রথমটি (কোনও স্থান ছাড়াই) '-4' হিসাবে প্রসারিত হবে যদি ভ্যার দ্বিতীয়টি সেট না করা হয় (একটি স্থান সহ) শেষের 4 টি বর্ণের অক্ষর দেয়।
pbatey

1
ব্যাশে, এটি "[: ==: আনারি অপারেটর প্রত্যাশিত" ত্রুটি তৈরি করবে যদি না আপনি প্রথম ভেরিয়েবলের চারপাশে উদ্ধৃতি স্থাপন করেন। if [ "${file: -4}" == ".txt" ]পরিবর্তে তাই ।
গিলস বি

264

মেক

if [ "$file" == "*.txt" ]

এটার মত:

if [[ $file == *.txt ]]

অর্থাৎ ডাবল বন্ধনী এবং কোনও উদ্ধৃতি নেই।

এর ডান দিকটি ==একটি শেল প্যাটার্ন। আপনার যদি নিয়মিত মত প্রকাশের প্রয়োজন হয় =~তবে ব্যবহার করুন ।


15
আমি এই সম্পর্কে জানতাম না। এটি একটি বিশেষ ক্ষেত্রে বলে মনে হচ্ছে যে == বা! = এর ডান হাতটি শেল প্যাটার্ন হিসাবে প্রসারিত হয়েছে। ব্যক্তিগতভাবে আমি মনে করি এটি আমার উত্তরের চেয়ে পরিষ্কার।
পল স্টিফেনসন

20
আমি মারতে নতুন এবং একাধিক শর্তাধীন ifবিবৃতিতে কীভাবে এটি ব্যবহার করতে হবে তা নির্ধারণ করতে আমার কিছুটা সময় লেগেছে । এটি কারও সাহায্য করার ক্ষেত্রে আমি এটি এখানে ভাগ করছি। if [[ ( $file == *.csv ) || ( $file == *.png ) ]]
joelostblom

6
@ চেফ্লো এটি সাধারণভাবে একাধিক শর্তের জন্য ভাল। এই নির্দিষ্ট ক্ষেত্রে, আপনি ব্যবহার করতে পারেন if [[ $file =~ .*\.(csv|png) ]]। এটি সংক্ষিপ্ত, পরিষ্কার, অতিরিক্ত এক্সটেনশন যুক্ত করা সহজ এবং সহজেই কনফিগারযোগ্য ("ভেরিয়েবলে" সিএসভি | পিএনজি "লাগিয়ে) তৈরি করা যেতে পারে।
জোকস

4
আপনি ফাইলটির চারপাশে ডাবল উদ্ধৃতি রাখতে পারেন। if [[ "$file" == *.txt ]]যদি ফাইলটির নামে ফাঁকা স্থান থাকে তবে ডাবল-উদ্ধৃতি আবশ্যক।
shawnhcorey

আমি কি এই উত্তরটি গ্রহণযোগ্য উত্তরটির পরিবর্তে ব্যবহার করব?
ফ্রিডো

26

আপনি কোনও ইউনিক্স সিস্টেমে নিশ্চিত হতে পারবেন না যে। টেক্সট ফাইলটি সত্যই একটি পাঠ্য ফাইল। আপনার সেরা বাজি "ফাইল" ব্যবহার করা। ব্যবহার করার চেষ্টা করুন:

file -ib "$file"

তারপরে আপনি মাইমে টাইপের একটি তালিকা ব্যবহার করতে পারেন বা MIME এর প্রথম অংশটি পার্স করতে পারেন যেখানে আপনি "পাঠ্য", "অ্যাপ্লিকেশন" ইত্যাদির মতো জিনিস পেয়ে থাকেন get


2
যেমন file -i...মাইম এনকোডিং অন্তর্ভুক্ত রয়েছে, আপনি ব্যবহার করতে পারেনfile --mime-type -b ...
উইলফ

24

আপনি যদি এক্সটেনশানগুলির উপর নির্ভর না করে প্রকৃতপক্ষে ফাইল সম্পর্কে তথ্য জানতে চান তবে আপনি "ফাইল" কমান্ডটি ব্যবহার করতে পারেন।

আপনি যদি এক্সটেনশানটি ব্যবহার করে স্বাচ্ছন্দ্য বোধ করেন তবে আপনি গ্রেপ ব্যবহার করতে পারেন এটি মিলছে কিনা তা দেখতে।


হ্যাঁ আমি fileআদেশ সম্পর্কে অবগত । আমি আসলে কমান্ডের আউটপুটের ভিত্তিতে মিলের চেষ্টা করেছি ... তবে আমি যদি এই বিবৃতিতে মারাত্মকভাবে ব্যর্থ হই।

17

আপনি এছাড়াও করতে পারেন:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi

11
case $FILE in *.txt ) ... ;; esacআরও দৃust় এবং মূ .় মনে হবে।
ট্রিপলি

11

'ফাইল' এর অনুরূপ, সামান্য সরল 'মিমিটাইপ-বি' ব্যবহার করুন যা ফাইলের এক্সটেনশনের কোনও বিষয় নয় work

if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
  echo "this is a text file"
fi

সম্পাদনা করুন: মাইম টাইপটি উপলব্ধ না হলে আপনার সিস্টেমে লাইবফাইল-মাইমেনফো-পার্ল ইনস্টল করতে হবে may


1
আপনার পরিষ্কার করা উচিত যে 'মিমটাইপ' স্ক্রিপ্ট সমস্ত সিস্টেমে উপলব্ধ নেই।
গিলবার্টপিলিজ

সম্পন্ন, লিবিফাইল-মাইমেনফো-পার্ল যুক্ত
দারগাড

5

লিনাক্সের একটি ফাইল নামটিতে এক্সটেনশনটি কীভাবে নেওয়া যায় তার সঠিক উত্তরটি হ'ল:

${filename##*\.} 

ডিরেক্টরিতে সমস্ত ফাইল এক্সটেনশন মুদ্রণের উদাহরণ

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done

আপনার উত্তরটি একটি ডাবল ব্যাকস্ল্যাশ ব্যবহার করে তবে আপনার উদাহরণটি কেবল একটি একক ব্যাকস্ল্যাশ ব্যবহার করে। আপনার উদাহরণটি সঠিক, আপনার উত্তর নেই।
গিলবার্টপিলিজ

3

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

#!/bin/bash
# flvcache script

CACHE=~/.mozilla/firefox/xxxxxxxx.default/Cache
OUTPUTDIR=~/Videos/flvs
MINFILESIZE=2M

for f in `find $CACHE -size +$MINFILESIZE`
do
    a=$(file $f | cut -f2 -d ' ')
    o=$(basename $f)
    if [ "$a" = "Macromedia" ]
        then
            cp "$f" "$OUTPUTDIR/$o"
    fi
done

nautilus  "$OUTPUTDIR"&

এটি এখানে উপস্থাপিতদের অনুরূপ ধারণাগুলি ব্যবহার করে, আশা করি এটি কারও পক্ষে সহায়ক।


2

আমি অনুমান করি যে '$PATH_TO_SOMEWHERE'এটির মতো কিছু '<directory>/*'

এই ক্ষেত্রে, আমি কোডটি এতে পরিবর্তন করব:

find <directory> -maxdepth 1 -type d -exec ... \;
find <directory> -maxdepth 1 -type f -name "*.txt" -exec ... \;

আপনি যদি ডিরেক্টরি এবং পাঠ্য ফাইলের নামগুলির সাথে আরও জটিল কিছু করতে চান তবে আপনি এটি করতে পারেন:

find <directory> -maxdepth 1 -type d | while read dir; do echo $dir; ...; done
find <directory> -maxdepth 1 -type f -name "*.txt" | while read txtfile; do echo $txtfile; ...; done

যদি আপনার ফাইলের নামগুলিতে ফাঁক থাকে তবে আপনি তা করতে পারেন:

find <directory> -maxdepth 1 -type d | xargs ...
find <directory> -maxdepth 1 -type f -name "*.txt" | xargs ...

শেলটিতে আপনি কীভাবে 'লুপগুলি' করেন তার দুর্দান্ত উদাহরণ। যখন লুপের শরীর আরও জটিল হওয়ার দরকার হয় তখন স্পষ্টত forএবং whileলুপগুলি আরও ভালভাবে সংরক্ষণ করা যায়।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.