फ़ाइल नामों को सूचीबद्ध करने के लिए कमांड का उपयोग कैसे करें लेकिन पथ नहीं?
मैंने ऑनलाइन कुछ उत्तरों की जाँच की है, लेकिन वे तब काम नहीं करते हैं जब -name
कमांड में कोई पैरामीटर हो (हो सकता है कि मैं कुछ गलत कर रहा हूँ, निश्चित नहीं)। मैं जो करना चाहता हूं वह केवल फ़ाइल नाम (निर्देशिका / पथ नहीं) सूचीबद्ध करने के लिए है, और अधिक जटिल करने के लिए, मेरे पास अलग-अलग एक्सटेंशन के साथ एक ही फ़ाइल नाम है, इसलिए मुझे परिणाम का उपयोग करके फ़िल्टर करने की आवश्यकता है -name
और -o
, परेशानी यह है कि सुझाव -printf
या तो उपयोग देखा या basename
, और जब वहाँ अच्छी तरह से काम नहीं करता है -name *.txt -o name *.pdf
। क्या इस समस्या को हल करने का कोई और तरीका है?
मेरी फ़ाइलों का उदाहरण:
/dir1/dir2/dir3/dir4/
/file1.txt
/file1.pdf
/file1.ods ...etc.
मैं केवल प्रति सूची एक या अधिक प्रकार की फ़ाइल सूचीबद्ध करने में दिलचस्पी रखता हूं ( -name
मेरे परिणामों को फ़िल्टर करने के लिए उपयोग करके)
क्या इसे केवल 1 find
कमांड का उपयोग करके पूरा करना संभव है या मुझे इसे 2 चरणों में करना होगा (परिणाम को अस्थायी फ़ाइल में सहेजना है, फिर निर्देशिका को अस्थायी फ़ाइल से फ़िल्टर / पट्टी करना)? परिणाम मैं पूरा करने की कोशिश कर रहा हूँ प्रति पंक्ति फ़ाइल नाम के साथ एक पाठ फ़ाइल है:
file1.txt
file1.pdf
file1.ods
file2.txt
file2.pdf
etc.
मैं जिस कमांड का उपयोग कर रहा था वह है
find /dir1/dir2/dir3/dir4/ -type f -name '*.txt' -o -name '*.pdf' -o -name '*.ods' -printf "%f\n"
मैं ग्नू खोज का उपयोग कर रहा हूं।
अपडेट करें
यह निकला कि मुझे \(...\)
αнsнι to द्वारा याद दिलाना है
जवाब
जब -o
आपके साथ तार्किक या मोड में कई अभिव्यक्तियों का उपयोग किया जाता है \( ... \)
, तो उन्हें उन सभी को संलग्न करने की आवश्यकता होती है , अन्यथा अंतिम अभिव्यक्ति परिणाम हमेशा सम्मानित होता है; और -printf '%f\n'
फ़ाइलों का नाम केवल किसी भी प्रमुख निर्देशिका को हटाने के साथ मुद्रित करने के लिए उपयोग किया जाता है।
find . -type f \( -name '*.pdf' -o -name '*.txt' \) -printf '%f\n'
OPERATORS अनुभाग के man findअंतर्गत देखें :( expr )
OPERATORS
...(expr)
बल पूर्वता। चूंकि कोष्ठक खोल के लिए विशेष हैं, इसलिए आपको आमतौर पर उन्हें उद्धृत करने की आवश्यकता होगी।
तो आप या तो उपयोग कर सकते हैं \( ... \)
या '(' ... ')'
(कोष्ठक के पहले और बाद में व्हाट्सएप महत्वपूर्ण हैं) उन्हें बचने के लिए।
जैसा कि पहले ही उल्लेख किया गया है, आपको अपने -name
परीक्षणों को कोष्ठकों में समूहित करने की आवश्यकता है। इन कोष्ठकों को शेल से बचाने के लिए \( ... \)
उदाहरण के रूप में भाग जाने या उद्धृत करने की आवश्यकता होती है '(' ... ')'
(जहां वे अन्यथा एक उपसमुच्चय को नामित करेंगे)।
मानक का उपयोग करना find
, और फ़ाइल नाम प्रत्ययों को संभालना भी थोड़ा आसान है:
set -- txt pdf ods
for suffix do
set -- "$@" -o -name "*.$suffix"
shift
done
shift
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename {} \;
यह पहले फ़ाइल नाम प्रत्यय की सूची में स्थितीय मापदंडों को निर्धारित करता है जिसे हम देखना चाहते हैं (इसे कमांड लाइन से भी लिया जा सकता है यदि यह एक स्क्रिप्ट है), और -name
परीक्षण की OR- सूची का निर्माण करता है । यह तब find
कमांड लाइन में उपयोग किया जाता है ।
find
आदेश में ही तो कहता है basename
प्रत्येक मिली नाम के लिए उपयोगिता।
एक विकल्प के रूप में, हम इसके बजाय सभी pathname के फ़ाइल नाम घटक को हटाने के लिए एक पैरामीटर प्रतिस्थापन का उपयोग कर सकते हैं, लेकिन ऐसा करने के लिए हमें एक इनलाइन sh -c
स्क्रिप्ट में pathnames को पास करना होगा :
# [...] as before [...]
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec sh -c '
for pathname do
printf "%s\n" "${pathname##*/}"
done' sh {} +
मैं उम्मीद करूंगा कि इसका उपयोग भिन्नता की तुलना में अधिक तेज होगा basename
, कम से कम यदि कई फाइलनेम को संभालना है, हालांकि जीएनयू basename
से कोर्यूटिल्स, आप उपयोग कर सकते हैं -a
या --multiple
पसंद कर सकते हैं :
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename -a {} +
यह basename
संभव के रूप में कुछ समय के लिए कहेंगे । लेकिन फिर, अगर आपने कोरुटिल्स स्थापित किए थे, तो आपके पास जीएनयू के साथ-साथ अच्छी तरह से फाइयूटिल्स भी find
हो सकते हैं, और -printf '%f\n'
वही काम करने के लिए उपयोग कर सकते हैं ।