পুনরাবৃত্তভাবে একটি নির্দিষ্ট এক্সটেনশন সহ ফাইলগুলি সন্ধান করুন


437

আমি আমার বাশ (সর্বশেষ উবুন্টু এলটিএস প্রকাশ) এর সাথে একটি ডিরেক্টরি এবং এর উপ-ডিরেক্টরিতে একটি নির্দিষ্ট বর্ধনের সাথে সমস্ত ফাইল সন্ধান করার চেষ্টা করছি।

এটি একটি স্ক্রিপ্ট ফাইলে যা লেখা হয়েছে:

#!/bin/bash

directory="/home/flip/Desktop"
suffix="in"

browsefolders ()
  for i in "$1"/*; 
  do
    echo "dir :$directory"
    echo "filename: $i"
    #   echo ${i#*.}
    extension=`echo "$i" | cut -d'.' -f2`
    echo "Erweiterung $extension"
    if     [ -f "$i" ]; then        

        if [ $extension == $suffix ]; then
            echo "$i ends with $in"

        else
            echo "$i does NOT end with $in"
        fi
    elif [ -d "$i" ]; then  
    browsefolders "$i"
    fi
  done
}
browsefolders  "$directory"

দুর্ভাগ্যক্রমে, আমি যখন এই স্ক্রিপ্টটি টার্মিনালে শুরু করি তখন এটি বলে:

[: 29: in: unexpected operator

(এর $extensionপরিবর্তে 'in')

এখানে কি হচ্ছে, ত্রুটি কোথায়? তবে এই কোঁকড়া ধনুর্বন্ধনী


2
ত্রুটিটি নিখোঁজ '{' থেকে হয়েছে
শ্রাইমাউস

উত্তর:


750
find $directory -type f -name "*.in"

পুরো জিনিসটির তুলনায় কিছুটা ছোট

আপনার স্ক্রিপ্ট সম্ভবত খালি .তৈরি করে এমন নামগুলিতে ব্যর্থ হচ্ছে যেগুলির নাম নেই $extension


16
হ্যাঁ, findডিফল্টরূপে পুনরাবৃত্ত হয়। আপনি চাইলে আপনি গভীরতা সীমাবদ্ধ করতে পারেন (ম্যান পৃষ্ঠাটি দেখুন)।
মাদুর

1
আমি সমস্ত পাওয়া ফাইলগুলি একটি জার-ফাইলে আর্গুমেন্ট হিসাবে পাস করতে চাই। এটি কীভাবে সম্পাদন করা যায়?
ফ্লিপ করুন

8
@ ফ্লিপ: এটি একটি আলাদা প্রশ্ন। আপনি কী করতে চান এবং এখন পর্যন্ত আপনি কী চেষ্টা করেছেন সে সম্পর্কে বিশদ বিবরণ দিয়ে একটি নতুন প্রশ্ন পোস্ট করুন।
মাদুর

একটি সামান্য সংশোধন: "* .in" এর পরিবর্তে '* .in' বা \ *। ব্যবহার করুন কারণ ডাবল উদ্ধৃতি শেল প্রসারণ রোধ করে না। অর্থাৎ বর্তমান ডিরেক্টরিতে .in এক্সটেনশন সহ কোনও ফাইল থাকলে আপনার স্ক্রিপ্টটি সঠিকভাবে কাজ করবে না।
শ্নাতসেল

4
@ স্ননাটসেল: দ্বিগুণ উদ্ধৃতি শেল সম্প্রসারণ রোধ করে। চেষ্টা কর.
মাদুর

188
find {directory} -type f -name '*.extension'

উদাহরণ:csv বর্তমান ডিরেক্টরি এবং এর উপ ডিরেক্টরিতে সমস্ত ফাইল সন্ধান করতে ব্যবহার করুন:

find . -type f -name '*.csv'

60

আমি যে সিনট্যাক্সটি ব্যবহার করছি তা @ ম্যাট যা বলেছিল তার থেকে কিছুটা আলাদা:

find $directory -type f -name \*.in

(এটি একটি কম কীস্ট্রোক)।


1
বর্তমান ডিরেক্টরিতে .in এক্সটেনশন সহ কোনও ফাইল উপস্থিত থাকলে ম্যাট এর স্ক্রিপ্টও কাজ করবে না, যদিও আপনার এখনও কাজ করবে। দেখুন stackoverflow.com/questions/5927369/...
Shnatsel

4
@ স্নাতসেল এই মন্তব্য (এবং তাই আপনার) স্পষ্টত ভুল।
gniourf_gniourf

1
@gniourf_gniourf আপনার বক্তব্যের জন্য আপনার কিছু রেফারেন্স সরবরাহ করা উচিত, অন্যথায় কেউ কেবল তর্ক করতে পারে: "না, আপনি ভুল" are কিন্তু আপনি আসলে আছেন ডানে: gnu.org/software/bash/manual/html_node/Double-Quotes.html
Murmel

@ ব্যবহারকারী 1885518: আমি মনে করি যে এই লোকটি হওয়া উচিত যে দাবি করে যে স্ক্রিপ্টটি কাজ করে না যেখানে স্ক্রিপ্টটি ব্যর্থ হয় সেখানে কিছু উদাহরণ প্রদান করা উচিত। আমি যেখানে মন্তব্যগুলি ছেড়ে দিই সেখানে ভাঙা স্ক্রিপ্টগুলি আমি তা করি: এটি প্রায়শই স্পেস, নিউলাইনস, গ্লোবস, ইত্যাদি সম্বলিত কোট এবং ফাইল নামগুলির সম্পর্কে এবং আমি কেন স্পষ্টভাবে ব্যাখ্যা করেছি তা স্পষ্টভাবে ব্যাখ্যা করি।
gniourf_gniourf

2
রেফারেন্স সরবরাহ করা সর্বদা আলোচনার একটি ভাল উপায়, এটি প্রথম কে ছিল তার উপর নির্ভর করে না। তিনি উচিত, আপনার উচিত।
মুরমেল

14

ব্যবহার না করে find:

du -a $directory | awk '{print $2}' | grep '\.in$'

3
grepএখানে সত্যিই প্রয়োজন হয় না। awkনিয়মিত এক্সপ্রেশন থাকে এবং এর আউটপুটটিকে কোনও প্যাটার্নের সাথে মানের মান সীমিত করতে পারে could
কেনসটার

আপনার পদ্ধতিটি 100 টি টেরাবাইটের মধ্য দিয়ে যেতে পারলে এই পদ্ধতিটি অত্যন্ত কার্যকর। ফাইন্ড কমান্ডটি প্রক্রিয়া করতে খুব বেশি সময় নেয়। এটি সঙ্গে সঙ্গে শুরু হয়।
প্রোটনোভা

1
awk|grepএকটি বিরোধী নিদর্শন। চলো গ্রেপিং করুক
জেনস

10
  1. {পরে নিখোঁজ আছেbrowsefolders ()
  2. সব $inহওয়া উচিত$suffix
  3. রেখাটি cutআপনাকে কেবলমাত্র মধ্যম অংশে পেয়ে যায় front.middle.extension। আপনার শেল ম্যানুয়ালটি আপনার ${varname%%pattern}এবং বন্ধুদের পড়া উচিত ।

আমি ধরে নিলাম আপনি শেল স্ক্রিপ্টিংয়ের অনুশীলন হিসাবে এটি করেন, অন্যথায় findইতিমধ্যে প্রস্তাবিত সমাধান হ'ল উপায়।

কোনও স্ক্রিপ্ট না চালিয়ে সঠিক শেল সিনট্যাক্স পরীক্ষা করতে ব্যবহার করুন sh -n scriptname



7

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

বর্ধিত বিকল্পটি extglobযা shoptনীচের মত বিকল্প ব্যবহার করে সেট করা দরকার । বিকল্পগুলি -sসমর্থন সহ সক্ষম করা হয়েছে এবং তিনি -uপতাকা সহ অক্ষম করেছেন । অতিরিক্ত হিসাবে আপনি আরও কয়েকটি বিকল্প ব্যবহার করতে পারেন nullglob, যাতে শূন্য শব্দের সংকলনের সাথে এক মিলিত গ্লোব পুরোপুরি সরে যায়। এবং globstarএটি সমস্ত ডিরেক্টরি মাধ্যমে পুনরাবৃত্তি করতে পারবেন

shopt -s extglob nullglob globstar

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

উদাহরণস্বরূপ *.csvপুনরাবৃত্ত পথে সমস্ত ফাইল তালিকাভুক্ত করা

fileList=(**/*.csv)

বিকল্পটি **সাব-ফোল্ডারগুলির মাধ্যমে পুনরাবৃত্তি করা এবং *.csvউল্লিখিত এক্সটেনশনের কোনও ফাইল অন্তর্ভুক্ত করার জন্য গ্লোব সম্প্রসারণ is আসল ফাইলগুলি মুদ্রণের জন্য এখনই করুন

printf '%s\n' "${fileList[@]}"

শেল স্ক্রিপ্টগুলিতে ব্যবহার করার সময় একটি অ্যারের ব্যবহার এবং সঠিক উদ্ধৃত সম্প্রসারণ করা সঠিক উপায়, তবে ইন্টারেক্টিভ ব্যবহারের জন্য আপনি কেবল lsগ্লোব এক্সপ্রেশন দিয়ে যেমন ব্যবহার করতে পারেন

ls -1 -- **/*.csv

একাধিক ফাইলের অর্থাত্ ফাইলটি একাধিক এক্সটেনশনের সমাপ্তি (যেমন findকমান্ডে একাধিক পতাকা যুক্ত করার অনুরূপ ) মেলাতে এটি খুব ভালভাবে প্রসারিত হতে পারে । উদাহরণ হিসেবে বলা যায় সব রিকার্সিভ ইমেজ ফাইল পেতে প্রয়োজন একটি মামলা বিবেচনা এক্সটেনশন অর্থাৎ *.gif, *.pngএবং *.jpg, সমস্ত আপনিই প্রয়োজন

ls -1 -- **/+(*.jpg|*.gif|*.png)

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

excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"

কনস্ট্রাক্টটি !()ভিতরে তালিকাভুক্ত কোনও ফাইল এক্সটেনশান অন্তর্ভুক্ত না করার জন্য একটি নিন্দিত অপারেশন এবং গ্লোবগুলির |একটি ওআর ম্যাচ করার জন্য বর্ধিত নিয়মিত এক্সপ্রেশন লাইব্রেরিতে যেমন ব্যবহৃত হয় তেমন একটি বিকল্প অপারেটর।

নোট করুন যে এই প্রসারিত গ্লোব সমর্থনটি পসিক্স বোর্ন শেলটিতে উপলভ্য নয় এবং এর সাম্প্রতিক সংস্করণগুলির জন্য এটি সম্পূর্ণরূপে নির্দিষ্ট bash। সুতরাং আপনি যদি পসিক্স এবং bashশেলগুলি জুড়ে স্ক্রিপ্টগুলির বহনযোগ্যতার বিষয়টি বিবেচনা করছেন তবে এই বিকল্পটি সঠিক হবে না।


6

pom.xmlআপনার বর্তমান ডিরেক্টরিতে সমস্ত ফাইল সন্ধান করতে এবং সেগুলি মুদ্রণ করতে আপনি ব্যবহার করতে পারেন:

find . -name 'pom.xml' -print


0
for file in "${LOCATION_VAR}"/*.zip
do
  echo "$file"
done 

1
এই কোডটি প্রশ্নের উত্তর দিতে পারে, কেন এবং / অথবা এই কোডটির প্রশ্নের উত্তর কীভাবে তার দীর্ঘমেয়াদী মানকে উন্নত করে সে সম্পর্কে অতিরিক্ত প্রসঙ্গ সরবরাহ করে।
রোলস্টুহফলাহার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.