অনুসন্ধান অনুসন্ধানে ডিরেক্টরি বাদ দিন


14

locateফাইল সিস্টেমে পাথগুলি সহ একটি অনুসন্ধান ।
প্রায়শই আপনি কেবলমাত্র ফাইল, বা কেবল ডিরেক্টরিতে ডিরেক্টরিতে আগ্রহী এমন একটি অগ্রাধিকার জানেন।
একটি 'সনাক্তকরণ' অনুসন্ধান প্রায়শই অনেক ফলাফল দেয়। ফলাফলের মধ্যে কেবল এক ধরণের অন্তর্ভুক্ত করা দরকারী হবে কারণ এটি আউটপুটকে সংক্ষিপ্ত করতে সহায়তা করে।

তবে ফাইল বা ডিরেক্টরিগুলি ছেড়ে দেওয়ার জন্য আরও আকর্ষণীয় যুক্তি রয়েছে: কারণ ফলাফলের পথগুলির তালিকা অস্পষ্ট হতে পারে - কেবল তাত্ত্বিকভাবেই নয়।

নীচের উদাহরণটি একটি বাস্তব বিশ্বের কেস, এবং অস্বাভাবিক নয়:

$ locate --regex --basename "xfce4-keyboard-overlay$"
/usr/local/bin/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay

ঠিক আছে, আমরা কিছু খুঁজে পেয়েছি! কিন্তু ... ফাইল, বা ডিরেক্টরি?

$ file /usr/local/bin/xfce4-keyboard-overlay 
/usr/local/bin/xfce4-keyboard-overlay:   bash script

সুতরাং এটি একটি ফাইল ...

$ file /usr/local/share/xfce4-keyboard-overlay
/usr/local/share/xfce4-keyboard-overlay: directory

দ্বিতীয়টি না হয়।

এই অস্পষ্টতাটি পাথের দীর্ঘ তালিকাগুলি পড়ার পক্ষে শক্ত করে তুলছে, সুতরাং ডিরেক্টরিগুলি ফিল্টার করে আউট করা সত্যিই দুর্দান্ত লাগবে, উদাহরণস্বরূপ একটি কমমান লাইন বিকল্পটি ব্যবহার করে locate

এর মতো কিছু আছে কি? এমনকি ডিরেক্টরিগুলির জন্য ফিল্টার যদি সনাক্ত করা থেকে পৃথক হয়?

কমপক্ষে, কোনও ফাইল স্ক্রিপ্ট ব্যবহার করে সমস্ত ফাইলের নামগুলি পরীক্ষা করতে চেক করতে পারে - যা ধীর হতে পারে।

উত্তর:


3

সহ zsh:

print -rl ${(0)^"$(locate -0 ...)"}(N.)

(0)একটি প্যারামিটার সম্প্রসারণ পতাকা যা NUL অক্ষরগুলিতে বিভক্ত হয় (যেমন আমরা ব্যবহার করি locate -0) এর জন্য সংক্ষেপে (ps:\0:)

সঙ্গে ^, পরিবর্তে যোগ করার (N.)অ্যারের শেষে, আমরা প্রতিটি উপাদান যোগ করুন।

(N.)একটি .নিয়মিত ফাইলের সাথে ম্যাচ করা, কেবলমাত্র নিয়মিত ফাইলের সাথে মেলে, Nএটি মেলে না থাকলে উপাদানটি সরিয়ে ফেলতে (উপস্থিত নেই বা একটি নিয়মিত ফাইল নয়, বা আমরা পরীক্ষা করতে পারি না) হ'ল একটি গ্লোব যোগ্যতা অর্জনকারী । আপনি কেবলমাত্র নিয়মিত ফাইলের পরিবর্তে নন-ডিরেক্টরিগুলি মিলানোর ^/পরিবর্তে ব্যবহার করতে পারেন .

print -rlপ্রতিটি যুক্তি একটি পৃথক লাইনে কাঁচা প্রিন্ট করে ।

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

(নোট করুন এটি যদি ব্যর্থ হয় তবে শেষ ফাইলটি locateনতুন লাইনের অক্ষরগুলিতে শেষ হয়ে যায় (সমস্ত শেলের মধ্যে একটি কমান্ড প্রতিস্থাপনের ভুল ব্যবহার))।


3

এটি অন্যান্য উত্তরগুলির মতোই অদম্য, তবে সম্ভবত কম অদক্ষ:

locate --regex --basename "xfce4-keyboard-overlay$" | 
        while IFS= read -r f; do [ -f "$f" ] && printf "%s\n" "$f"; done

(পাঠযোগ্যতার জন্য দুটি লাইনে বিভক্ত) উপরের স্থানগুলি সম্বলিত নামগুলি পরিচালনা করবে। IFS=সঙ্গে নাম হ্যান্ডেল করার প্রয়োজন হতে বলে মনে হয় trailing ব্যবধান এবং, অবশ্যই, -rআপনি ব্যাকস্ল্যাশ হ্যান্ডেল করতে দেয়।

" locateনতুন কিছু যুক্ত রাস্তা" উপস্থিত থাকলে "আসুন কিছুতে পাইপ দিন " পদ্ধতির ব্যর্থতা বিনষ্ট হতে পারে।


আরও তথ্যের জন্য IFS, পড়া sh(1)বা bash(1) (টাইপ করে man shবা man bashএকটি * স্নো সিস্টেমের মধ্যে, এবং / অথবা এটা পড়া এখানে , এখানে , এখানে , এবং / অথবা এখানে )। তারপরে আইএফএস এবং ব্যাশ বোঝার জন্য পড়ুন : স্ট্যাক এক্সচেঞ্জে আইএফএসের সাথে এক এক করে লাইন পড়ুন (5 টিরও বেশি ভোট দিয়ে উত্তরগুলিতে ফোকাস করুন) এবং, আপনার এখনও পর্যাপ্ত পরিমাণ না থাকলে গ্রেগের উইকি এবং আইএফএস অনুসন্ধান ফলাফলগুলিতে আইএফএস পরীক্ষা করে দেখুন বাশ হ্যাকার উইকিতে (স্ট্যাক এক্সচেঞ্জে নেই)


আপনার whileবিবৃতিটি "আইএফএস =" কি করার পরে আপনি কিছু তথ্য যুক্ত করতে পারেন ?
রবার্ট

আমি তাই করেছি।
জি-ম্যান

ব্যাকস্ল্যাশগুলি এখনও অনেক প্রতিধ্বনি বাস্তবায়নে সমস্যা হবে। আপনার printfযথেচ্ছ ডেটা ব্যবহার করা উচিত
স্টাফেন চেজেলাস 12

আপনার নতুন লাইনের সমস্যার সমাধান হতে পারে "--null" প্যারামিটারটি ব্যবহার করে locateএবং আপনার readএখানে প্রস্তাবিত ট্রান্সমনাম.ব্লগস্পট.আই
রবার্ট ২

@ স্টাফেনচেজেলাস: ভালো কথা। সংশোধন করা হয়েছে।
জি-ম্যান

2
locate --null --regex --basename "xfce4-keyboard-overlay$" |
  xargs -r0 sh -c 'find "$@" -prune ! -type d' sh

আসলে, এটি দেখতে দেখতে আরও নোংরা ... তবে একটি ভাল পরিদর্শন। আসুন এটি সিডোকোডের ভান করুন, তারপরে এটি সহায়ক)
ভলকার সিগেল ২

1
@ ভোলকার: আমি সম্মত হই যে এটি খারাপ: এটি আপনার উদাহরণে /usr/local/share/xfce4-keyboard-overlay এবং এর প্রতিটি উপ-ডিরেক্টরিকে তালিকাভুক্ত করবে । যোগ করা -maxdepth 0সাহায্য করে।
জি-ম্যান 'পুনর্বহাল মনিকা' বলে

এটি আরও উন্নত হয় ...: ডি locate --regex --basename "xfce4-keyboard-overlay$" | xargs -I % sh -c "test -d % && echo %"
ফ্লোহাইমস্ফাল

1
ব্যবহার xargsসঙ্গে findএকটি ভাল ধারণা ছিল, আমি এটা শক্তসমর্থ করতে এটা সম্পাদনা করেছিলেন। আশা করি আপত্তি করবেন না।
স্টাফেন চেজেলাস 27'15

1

xargsপ্রতিটি পংক্তির জন্য কমান্ড পুনরাবৃত্তি করবে যদি আপনি নির্দিষ্ট -L 1বা -iপরামিতি করেন।

এখানে দেখো

$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i bash -c '(test -d "{}" && echo "{}")'

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

সম্পাদনা: আমি এই উত্তরটি নিয়ে বেশ খুশি ছিলাম না কারণ এটি প্রতিটি ফাইলের জন্য একটি নতুন শেলটি লাথি মারছিল। এটিতে কেবল দুটি প্রক্রিয়া হওয়া উচিত:

$ locate --regex --basename "xfce4-keyboard-overlay$" | xargs -i echo 'test -d "{}" && echo "{}"' | bash

অবশ্যই এটি চমৎকার হবে যদি আমরা পুরোপুরি একজন দোভাষীকে লাথি মারা এড়াতে পারি, তবে xargsকমান্ডগুলি সাজাতে তার ক্ষমতাকে হ্যামস্ট্রং বলে মনে হয়।


3
সে কেবলমাত্র আমার মেশিনটি পুনরায় বুট করেছিল (একটি ফাইল বলা হয়েছিল /home/evil/$(reboot)/xfce4-keyboard-overlayএবং আমি বোকামি করে এটি চালিয়েছি root)।
স্টাফেন চেজেলাস

2
"ইন্টারনেট থেকে র্যান্ডম কোডজ" মূল হিসাবে চালানোর সাহসের জন্য @ স্টাফেনচাজেলাস +1 করুন;) (স্ক্যানার)
ভোলকার সিগেল

0

আমার দুই সেন্ট:

while IFS= read i; \
do \
  if [ -f "$i" ]; \
  then \
    echo "$i"; \
  fi; \
done < <(locate --regex --basename "xfce4-keyboard-overlay$")

প্রক্রিয়া প্রতিস্থাপনের সাথে জি-ম্যান এটি যেভাবে করেছে এটি কমবেশি।


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

দুঃখিত। আমার ভুল. সংশোধন।
ত্রিস্তান স্টর্চ

-1

আপনি যদি একত্রিত locateহন fileএবং grep? ...

$ for f in `locate --regex --basename "xfce4-keyboard-overlay$"`; do file $f; done | grep -vi directory

আমি পরীক্ষা করিনি, তবে আমি মনে করি এটি ধীর হতে পারে, কারণ এটি fileপ্রতিটি একক পথের জন্য একটি প্রক্রিয়া তৈরি করে। মনে রাখবেন যে সনাক্ত করার জন্য ফলাফলের অনেকগুলি লাইন থাকে। আমার বর্তমান পরীক্ষাটি "জিনোম" অনুসন্ধান করছে, পরীক্ষার জন্য প্রায় 73000 পাথ দিচ্ছে।
ভোলকার সিগেল

2
@ ভোলকার: এটি এর চেয়েও খারাপ: প্রতিটি $fফাইলের জন্য, fileপ্রোগ্রামটি সেই ফাইলটি খুলবে এবং এটি থেকে পড়বে । এটি অত্যন্ত ব্যয়বহুল যখন আপনার যা করতে হবে তা হ'ল একটি stat()। ………… এছাড়াও, এটি তাদের নামে "ডিরেক্টরি" থাকা ফাইলগুলির জন্য ভুল ফলাফল দেবে (যেমন "ফোন_ ডিরেক্টরি")। ………… ... (এছাড়াও, for f in `…`; do …বাক্য গঠনটি শূণ্যস্থানগুলির নামগুলি পরিচালনা করতে পারে না))
জি-ম্যান বলে 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.