শেল স্ক্রিপ্টে ডিরেক্টরিতে ফাইলের তালিকা কীভাবে পাবেন?


159

আমি শেল স্ক্রিপ্ট ব্যবহার করে কোনও ডিরেক্টরিতে থাকা সামগ্রীগুলি পাওয়ার চেষ্টা করছি।

আমার লিপিটি হ'ল:

for entry in `ls $search_dir`; do
    echo $entry
done

যেখানে $search_dirএকটি আপেক্ষিক পথ তবে, $search_dirতাদের নামে সাদা জায়গাগুলি সহ অনেকগুলি ফাইল রয়েছে। সেক্ষেত্রে এই স্ক্রিপ্টটি প্রত্যাশার মতো চলবে না।

আমি জানি আমি ব্যবহার করতে পারি for entry in *, তবে এটি কেবলমাত্র আমার বর্তমান ডিরেক্টরিতে কাজ করবে।

আমি জানি যে আমি সেই ডিরেক্টরিতে পরিবর্তন করতে পারি, ব্যবহার করতে পারি আবার পরিবর্তন করতে পারি for entry in *তবে আমার বিশেষ পরিস্থিতি আমাকে তা করতে বাধা দেয়।

আমার দুটি আপেক্ষিক পাথ রয়েছে $search_dirএবং $work_dirএবং আমি উভয় একই সাথে কাজ করতে হবে, সেগুলিতে ফাইল তৈরি / মুছতে পঠন ইত্যাদি reading

তাহলে আমি এখন কি করব?

PS: আমি ব্যাশ ব্যবহার করি।

উত্তর:


274
for entry in "$search_dir"/*
do
  echo "$entry"
done

4
আপনি ব্যাখ্যা করতে পারেন কেন for entry in "$search_dir/*"কাজ করে না? আমাদের /*উদ্ধৃতিগুলির বাইরে কেন রাখা দরকার ?
mrgloom

6
@ মিগ্রলুম: কারণ আপনার শেলটি ওয়াইল্ডকার্ডকে দমন করতে হবে।
Ignacio Vazquez-Abram

findদ্রুত হবে না ?
আলেকজ মাগুরা

4
সমাধানটি পুরো পথ দেয়। যদি আমি কেবল বর্তমান ডিরেক্টরিটিতে কী ছিল তা তালিকাবদ্ধ করতে চাইতাম?
ThatsRightJack

1
@ মিগ্রলুম যদি আপনি এটি করতে চান তবে আপনি তা অর্জন করতে পারবেনfor entry in "${search_dir}/*"
ফানিলারিগুলি

28

এখানে অন্যান্য উত্তরগুলি দুর্দান্ত এবং আপনার প্রশ্নের উত্তর দিন, তবে এটি "ডিরেক্টরিতে ফাইলগুলির তালিকা পান", (যা আমি ফাইলগুলির একটি তালিকা সংরক্ষণ করার জন্য সন্ধান করছিলাম) এর শীর্ষ গুগল ফলাফল তাই আমি ভেবেছিলাম যে আমি একটি পোস্ট করব এই সমস্যার উত্তর:

ls $search_path > filename.txt

আপনি যদি কেবলমাত্র একটি নির্দিষ্ট ধরণের চান (যেমন কোনও। টেক্সট ফাইল):

ls $search_path | grep *.txt > filename.txt

মনে রাখবেন যে $ অনুসন্ধান_পথটি alচ্ছিক; ls> filename.txt বর্তমান ডিরেক্টরিটি করবে।


কেবলমাত্র টেক্সট ফাইলগুলি পেতে গ্রেপ ব্যবহার করার দরকার নেই: `ls $ Search_path / *। Txt> filename.txt '। তবে আরও গুরুত্বপূর্ণ, ফাইলের নামগুলি বিশ্লেষণের জন্য ls কমান্ডের আউটপুট ব্যবহার করা উচিত নয়।
ভিক্টর জামানমিয়ান

1
@ ভিক্টরজাম্যানিয়ান, আপনি কীভাবে ফাইলনাম lsপার্স করার জন্য আউটপুট ব্যবহার করবেন না তা আপনি ব্যাখ্যা করতে পারেন ? এর আগে শুনিনি।
সামুরাই_জানে

1
@ সামুরাই_জানে এই বিষয়টি সরবরাহ করার জন্য প্রচুর লিঙ্ক রয়েছে তবে এখানে প্রথম একটি অনুসন্ধান ফলাফল: mywiki.wooledge.org/ পার্সিংএলস । এমনকি আমি এখানে এসও-তে একটি প্রশ্ন দেখেছি যে দাবি করে যে এলএসের আউটপুট বিভক্ত না করার কারণগুলি বিএস ছিল এবং এটি সম্পর্কে খুব বিস্তৃত ছিল। তবে উত্তর / উত্তর এখনও দাবি করেছে যে এটি একটি খারাপ ধারণা। এক নজরে
ভিক্টর জামামানিয়ান

26

এটি করার একটি উপায় যেখানে সিনট্যাক্সটি আমার পক্ষে বোঝার পক্ষে সহজ:

yourfilenames=`ls ./*.txt`
for eachfile in $yourfilenames
do
   echo $eachfile
done

./বর্তমান কার্যনির্বাহী ডিরেক্টরি তবে যে কোনও পথই পরিবর্তিত হতে পারে যে কোনও
*.txtকিছুই প্রত্যাবর্তন করবে। txt
আপনি টাইপ করে যা সহজে তালিকাবদ্ধ করা হবে তা পরীক্ষা করতে পারেনls টেক্সটটি সরাসরি টার্মিনালে কমান্ডটি ।

মূলত, আপনি yourfilenamesতালিকা কমান্ডটি পৃথক উপাদান হিসাবে ফিরিয়ে দেয় এমন সমস্ত কিছু সহ একটি ভেরিয়েবল তৈরি করেন এবং তারপরে আপনি লুপ করেন। লুপটি একটি অস্থায়ী ভেরিয়েবল তৈরি করে যা ভেরিয়েবলের eachfileএকক উপাদানকে এর মধ্য দিয়ে লুপ করছে, এক্ষেত্রে একটি ফাইল নাম। এটি অন্য জবাবগুলির চেয়ে অগত্যা ভাল নয় তবে আমি এটি স্বজ্ঞাত মনে করি কারণ আমি ইতিমধ্যে lsকমান্ড এবং লুপ সিনট্যাক্সের সাথে পরিচিত ।


এটি তাত্ক্ষণিক, অনানুষ্ঠানিক স্ক্রিপ্ট বা ওয়ান-লাইনারের জন্য ঠিক আছে, তবে গ্লোব-ভিত্তিক সমাধানগুলির বিপরীতে কোনও ফাইলনেলে নতুন লাইন থাকলে তা ভেঙে যাবে।
সোরেন বর্জনস্টাড

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

ফাইলনামগুলিতে থাকা নিউলাইনগুলি এই কারণে খারাপ এবং যতদূর আমি জানি যে এগুলি ব্যবহার করার কোনও বৈধ কারণ নেই। আমি নিজে কখনও বুনোতে দেখিনি। এটি বলেছিল যে, এটির শোষণের জন্য এমনভাবে নিউলাইনগুলি সহ ফাইলের নামগুলি দূষিতভাবে তৈরি করা সম্পূর্ণভাবে সম্ভব। (উদাহরণস্বরূপ, কল্পনা একটি ডিরেক্টরি ফাইল ধারণকারী A, Bএবং C। আপনি নামক ফাইল তৈরি B\nCএবং D, তারপর তাদের মুছে ফেলতে চয়ন। সফ্টওয়্যার, যা হ্যান্ডেল নেই এই অধিকার শেষ পর্যন্ত পারে preexisting ফাইল B এবং C পরিবর্তে এমনকি মুছে ফেলার যদি আপনি ছিল না এটি করার অনুমতি))
সোরেন বোর্নস্ট্যাড


11
find "${search_dir}" "${work_dir}" -mindepth 1 -maxdepth 1 -type f -print0 | xargs -0 -I {} echo "{}"

1
আমি জানি এটি বেশ পুরানো তবে আমি শেষ xargs -0 -i echo "{}"কমান্ডটি পেতে পারি না , আমাকে কিছুটা ব্যাখ্যা করার জন্য যত্নশীল? বিশেষত -i echo "{}"অংশটি কী করে? এছাড়াও আমি manযে পৃষ্ঠাটি -iএখন -Iহ্রাস করা হয় তা থেকে পড়েছি এবং আমাদের উত্তাপযুক্ত ব্যবহার করা উচিত ।
drkg4b

1
-i{}আর্গ সঙ্গে বিকল্প ।
নোয়েল ইয়াপ

ধন্যবাদ! এটি দরকারী, আমার মতো ধীর মনের জন্যও আমি মনে করি যে কমান্ড {}দ্বারা ম্যাচগুলির সাথে প্রতিস্থাপন করা স্ট্রিং find
drkg4b

3
আপনি কেন ব্যবহার করবেন xargs? ডিফল্টরূপে, findএটি যা সন্ধান করে তা মুদ্রণ করে ... আপনি এ থেকে সমস্ত কিছু মুছতে পারেন -print0
gniourf_gniourf

1
এটি করা স্পেস সহ ভালভাবে ফাইল এন্ট্রি পরিচালনা করতে পারে না।
নোয়েল ইয়াপ

4
$ pwd; ls -l
/home/victoria/test
total 12
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  a
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  b
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  c
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:32 'c d'
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  d
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32  dir_a
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32  dir_b
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:32 'e; f'

$ find . -type f
./c
./b
./a
./d
./c d
./e; f

$ find . -type f | sed 's/^\.\///g' | sort
a
b
c
c d
d
e; f

$ find . -type f | sed 's/^\.\///g' | sort > tmp

$ cat tmp
a
b
c
c d
d
e; f

প্রকারভেদ

$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

মন্তব্য:

  • . : বর্তমান ফোল্ডার
  • অপসারণ -maxdepth 1পুনরাবৃত্তি অনুসন্ধান করতে
  • -type f : ফাইল অনুসন্ধান করুন, ডিরেক্টরি নয় (d )
  • -not -path '*/\.*' : ফিরে না .hidden_files
  • sed 's/^\.\///g': ./ফলাফল তালিকা থেকে চাপ দেওয়া অপসারণ

0

এখানে একটি ডিরেক্টরিতে ফাইল তালিকাভুক্ত করার আরেকটি উপায় রয়েছে (অন্য কোনও উত্তরের মতো দক্ষ নয়, একটি আলাদা সরঞ্জাম ব্যবহার করে)।

cd "search_dir"
for [ z in `echo *` ]; do
    echo "$z"
done

echo *বর্তমান ডিরেক্টরিতে সমস্ত ফাইল আউটপুট করে। দ্যforলুপ stdout- এ প্রতিটি ফাইল নাম এবং কপি করে প্রিন্ট উপর iterates।

অতিরিক্তভাবে, যদি ডিরেক্টরি ভিতরে ডিরেক্টরি অনুসন্ধান করা হয় তবে এটি forলুপের মধ্যে রাখুন:

if [ test -d $z ]; then
    echo "$z is a directory"
fi

test -d ফাইলটি ডিরেক্টরি কিনা তা পরীক্ষা করে।


0

গৃহীত উত্তর a দিয়ে ফাইলের উপসর্গটি ফেরত দেবে না। যে ব্যবহার করতে

for entry in "$search_dir"/* "$search_dir"/.[!.]* "$search_dir"/..?*
do
  echo "$entry"
done

-1

লিনাক্স সংস্করণে আমি নিম্নলিখিত (x86_64 জিএনইউ / লিনাক্স) সাথে কাজ করি:

for entry in "$search_dir"/*
do
  echo "$entry"
done

-1: এটি গ্রহণযোগ্য উত্তরের সাথে সমান এটি বাদে এটি ভেরিয়েবলের উদ্ধৃতি দেয় না। উদ্ধৃতি না দেওয়ার $search_dirঅর্থ ডিরেক্টরি নামের জায়গায় কোনও স্থান থাকলে তা ভেঙে যায়। ( $entry
এক্ষেত্রে

আপনি ভুল. আমার সমাধানটি একই নয়, এমনকি যখন এটি গৃহীত উত্তরের মতো হয়। এবং এটি ভুল নয়, এটি কাজ করে। এখানে আমি ম্যাক ওএস সহ বিভিন্ন ইউনিক্স সিস্টেমে যা চেষ্টা করেছি তা এখানে রয়েছে এবং এটি তাদের প্রতিটিটিতেই কাজ করেছে। শূন্যস্থানযুক্ত ফাইলটি এমনকি নামটিতে শীর্ষস্থানীয় ফাঁকা রয়েছে এমনকি সঠিকভাবে প্রদর্শিত হয়। search_dir =। প্রবেশের জন্য d অনুসন্ধান_ডির / *; প্রতিধ্বনি করুন $ প্রবেশ; সম্পন্ন। / aaaa.txt ./add ./apm_tables.txt আপনি যখন সমাধান প্রমাণিত করতে পারেন না বা ভুল ফলাফল তৈরি করে তা প্রমাণ করতে পারেন আপনি সমাধানগুলিকে ভোট দিতে পারেন।
এন্ড্রুশেঙ্কো আলেকজান্ডার

আপনি যদি আমার মন্তব্যটি আরও কাছাকাছি পড়েন তবে আপনি দেখতে পাবেন যে সমস্যাটি ফাইলের নাম নয়, ডিরেক্টরিটির নাম ফাঁকা রয়েছে । প্রশ্নকারীর যে ইস্যুটি ছড়িয়েছে তার চেয়ে এটি আলাদা, তবে এর অর্থ কোডটি অজান্তেই ভেঙে যেতে পারে! এখানে কাজ করে না এটি তার একটি উদাহরণ দেওয়া হল: । লুপটি দু'বার চালিত হয়, একবার মুদ্রণ এবং দ্বিতীয়বার , যা সম্ভবত প্রত্যাশিত ফলাফল নয়। mkdir "x y"; touch "x y/1.txt"; search_dir="x y"; for entry in $search_dir/*; do echo $entry; donexy/*
সোরেন জর্নস্ট্যাড

এবং আমি অযৌক্তিকভাবে অব্যবহৃত ভেরিয়েবলগুলি বিপজ্জনকভাবে ভুল বলে বিবেচনা করি, যা ডাউনভোটের ভিত্তি। ফাইলগুলি যাব অনুসন্ধান ডিরেক্টরি কোন সাবডিরেক্টরি মুছে ফেলতে এই কোড বিবেচনা করুন: search_dir="x y"; for entry in $search_dir/*; do if [ -d "$entry" ]; then rm -rf "$entry"; fi; done। যদি xবর্তমান ডিরেক্টরিতে কোনও ডিরেক্টরি থাকে তবে এটি সংক্ষেপে মুছে ফেলা হয়, কারণ আপনি নিজের ভেরিয়েবলটি উদ্ধৃত করেন নি!
সোরেন জর্নস্ট্যাড

ঠিক আছে, আপনি সবসময় একটি কাজের জন্য তৈরি কোড নেন, টাস্কটি সামান্য পরিবর্তন করুন এবং কোডটি ভুল হয়ে যায়। প্রশ্নের জন্য জিজ্ঞাসা আমার প্রস্তাবিত সমাধান কাজ করে। তবে ... একজন বিকাশকারী হওয়ায় আমাকে আপনার যুক্তিগুলির সাথে একমত হতে হবে: ওয়েেন আমরা একটি কোডকে আরও শক্তিশালী এবং জেনারোল তৈরি করতে পারি, আমাদের এটি করা উচিত। সুতরাং আমি কিউটিস যুক্ত করব। এটি আমার উত্তরটিকে উপরে বর্ণিত উত্তরের মতো করে তুলবে, তবে বিযুক্তির জন্য (এটি কারও পক্ষে কার্যকর হতে পারে) আমি উত্তরটিও রেখে দেব।
Andrushenko আলেকজান্ডার

-1

এই সহজ কমান্ডটি লিখুন:

ls -d */

আপনি কি কিছু ব্যাখ্যা দিতে পারবেন @ মিশেল সিসকো
বিপুল

ls (তালিকা) -d (কেবলমাত্র ডিরেক্টরিগুলির তালিকা তৈরি করুন) * / (যে কোনও প্যাটার্নের ব্যাকস্ল্যাশ কেবলমাত্র ডিরেক্টরিতে তালিকা সীমাবদ্ধ করে)।
মাইকেল সিসকো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.