मैं उन पीडीएफ फाइलों को खोजना चाहता हूं, जिनका नाम (विस्तार को छोड़कर) तीन से अधिक है।
$ find ~ -iregex ".{3,}/.pdf"
कुछ नहीं देता, लेकिन
$ find ~ -iregex ".+/.pdf"
काम करता है।
मैं {3,}
वेरिएंट को कैसे सक्षम कर सकता हूं ?
मैं उन पीडीएफ फाइलों को खोजना चाहता हूं, जिनका नाम (विस्तार को छोड़कर) तीन से अधिक है।
$ find ~ -iregex ".{3,}/.pdf"
कुछ नहीं देता, लेकिन
$ find ~ -iregex ".+/.pdf"
काम करता है।
मैं {3,}
वेरिएंट को कैसे सक्षम कर सकता हूं ?
जवाबों:
मान लें कि आप GNU का उपयोग कर रहे हैं find
(जो कि आप संभवतः हैं, चूंकि POSIX में-iregex
GNU एक्सटेंशन है ), और Emacs नियमित अभिव्यक्ति के लिए डिफ़ॉल्ट है, जो पहचान नहीं करते हैं । आपको विकल्प का उपयोग करके एक अलग प्रकार के नियमित अभिव्यक्ति निर्दिष्ट करने की आवश्यकता है ; इसके अलावा, आपको अपनी नियमित अभिव्यक्ति को इस तथ्य से समायोजित करने की आवश्यकता है कि अभिव्यक्ति पूर्ण पथ के खिलाफ मेल खाती है:find
-regex
-iregex
{3,}
-regextype
find ~ -regextype posix-extended -iregex '.*/[^/]{3,}.pdf'
आपको भी बचना चाहिए .
ताकि यह मेल खाता हो। किसी भी चरित्र के बजाय:
find ~ -regextype posix-extended -iregex '.*/[^/]{3,}\.pdf'
नियमित अभिव्यक्ति को सरल किया जा सकता है क्योंकि हम केवल तीन गैर - "/" वर्णों की परवाह करते हैं:
find ~ -regextype posix-extended -iregex '.*[^/]{3}\.pdf'
पूर्णता के लिए, FreeBSD या NetBSD के साथ find
(एक और कार्यान्वयन जो आपका समर्थन करता है -iregex
, न कि आपका यद्यपि .+
वहाँ काम नहीं करेगा -E
), आप लिखेंगे:
find ~ -iregex '.*[^/]\{3\}\.pdf'
या:
find -E ~ -iregex '.*[^/]{3}\.pdf'
बिना -E
, यह मूल नियमित अभिव्यक्ति है (जैसे grep
) और -E
विस्तारित नियमित अभिव्यक्ति (जैसे grep -E
)।
Ast- खुले के साथ find
:
find ~ -iregex '.*[^/]{3}\.pdf'
(यह बॉक्स से बाहर regexps विस्तारित है)।
यहाँ यह मानक वाइल्डकार्ड के साथ आसान है:
find ~ -name '*???.[pP][dD][fF]'
या कुछ find
कार्यान्वयन के साथ (जो समर्थन -regex
भी करते हैं -iname
):
find ~ -iname '*???.pdf'
इसके बजाय वर्णों की मनमानी संख्या के लिए 3
, वह है जहाँ आप -iregex
उपलब्ध होने के लिए वापस आना पसंद कर सकते हैं ( @Stephen Kitt का उत्तर देखें ) या आप उपयोग zsh
या ksh93
ग्लोब कर सकते हैं :
zsh
:
set -o extendedglob # best in ~/.zshrc
printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
(के (D)
साथ की तरह छिपा डायरियों में छिपी फाइलों और फाइलों पर विचार करने के लिए find
)
(#cx,y)
है zsh
regexp की वाइल्डकार्ड बराबर{x,y}
(#i)
मामले के लिए असंवेदनशील?
किसी भी एकल वर्ण के लिए मानक वाइल्डकार्ड (जैसे regexp .
)**/
: उपनिर्देशिकाओं के किसी भी स्तर (0 सहित)ksh93
:
FIGNORE='@(.|..)' # to consider hidden files
set -o globstar
printf '%s\n' **/{3,}(?).~(i:pdf)
@(x|y)
: regexp के समान विस्तारित ksh वाइल्डकार्ड ऑपरेटर (x|y)
।FIGNORE
: विशेष चर जो यह नियंत्रित करता है कि ग्लब्स द्वारा कौन सी फ़ाइलों को अनदेखा किया गया है। जब सेट किया जाता है, तो छिपी हुई फ़ाइलों की सामान्य रूप से अनदेखी नहीं की जाती है, लेकिन हम अभी भी मौजूद निर्देशिका .
और ..
निर्देशिका प्रविष्टियों को अनदेखा करना चाहते हैं ।{x,y}(z)
है ksh93
की regexp के बराबर z{x,y}
।~(i:...)
: केस-असंवेदनशील मिलान।यहाँ पर ग्लब्स के कुछ अतिरिक्त फायदे हैं find
जिसमें आपको एक क्रमबद्ध सूची मिलती है (आप ग्लोब क्वालिफायर के zsh
साथ उस छँटाई को अक्षम कर सकते हैं oN
, या विभिन्न छँटाई मानदंडों का उपयोग कर सकते हैं ) और यह भी काम करते हैं जब फ़ाइल नाम में बाइट्स का अनुक्रम होता है जो वैध वर्ण नहीं बनाते हैं (के लिए उदाहरण के लिए, UTF-8 चारसेट का उपयोग करते हुए एक लोकेल में, यह find
दृष्टिकोण रिपोर्ट करने में विफल होगा $'St\xE9phane Chazelas - CV.pdf
कि \xE9
कोई चरित्र regexp .
या वाइल्डकार्ड ?
या *
GNU के साथ मेल नहीं खाता है find
)।
shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
जब तक आप नहीं पूछेंगे आप नहीं। ज़रूर, मुझे पांडित्य हो रहा है, लेकिन आपने उनके नाम वाली फाइलों के.pdf
बारे में नहीं पूछा । सिर्फ इसलिए कि किसी फ़ाइल में फ़ाइल .pdf
नाम के वर्ण हैं, वह उसे PDF फ़ाइल नहीं बनाती है ।
वास्तव में, आइए इस बारे में सभी तरीके से पढ़ें: यदि किसी फ़ाइल के नाम के अंतिम चार अक्षर हैं .pdf
, तो उसके नाम में हमेशा तीन से अधिक वर्ण होंगे ।
तो यह गलत तरीका है , आप कह सकते हैं:
$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf
वह दूसरा देखें? यह वास्तव में एक निष्पादन योग्य है। (मुझे पता है, मैंने नाम बदल दिया है।) और मुझे एक पीडीएफ भी याद आ रही है जिसे मैं कर सकता था शपथ दस्तावेज निर्देशिका में थी ...
$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf
इसलिए -iname
हम इसका उपयोग कर सकते हैं, लेकिन यह अभी भी इस पीडीएफ फाइल को नहीं बदल रहा है।
इस मामले में हम वास्तव में क्या करना चाहते हैं , कमांड का उपयोग करके फ़ाइल के मैजिक नंबर की जांच करें file
। एक विकल्प MIME प्रकार को आउटपुट करता है , जो पार्स करने के लिए सरल है। find
क्वेरी तो एक सरल हो जाता है -name "???*"
।
$ find . -type f -name "???*" -print0|xargs -0 file --mime
./.bash_history: text/plain; charset=us-ascii
./.bash_logout: text/plain; charset=us-ascii
./.bashrc: text/plain; charset=us-ascii
./.profile: text/plain; charset=us-ascii
./Documents/McLaren 720s Coupe:Order Summary.pdf: application/pdf; charset=binary
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF: application/pdf; charset=binary
./Documents/Setup_MagicISO.exe.pdf: application/x-dosexec; charset=binary
./Downloads/Setup_MagicISO.exe: application/x-dosexec; charset=binary
./Downloads/WindowsUpdate.diagcab: application/vnd.ms-cab-compressed; charset=binary
चलो कोलोन सीमांकक का उपयोग करें, और MIME प्रकार की तलाश करें application/pdf
, फिर उस भाग को शून्य करें और परिणाम प्रिंट करें। ध्यान दें, मेरी एक फ़ाइल में नाम में एक कोलन है; इसलिए मैं सिर्फ awk से नहीं पूछ सकता ($2==":"){print $1}
।
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
अब पीडीएफ फाइल a
और नाम शामिल करने के लिए प्रयास करके समाप्त करते हैं abc
:
$ mkdir Documents/other
$ cp -a Documents/McLaren\ 720s\ Coupe\:Order\ Summary.pdf Documents/other/a
$ cp -a Documents/Pioneer\ Premier\ DEH-P490IB\ CD\ Install\ Manual.PDF Documents/other/abc
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
./Documents/other/abc
बस इतना ही। मुझे पता है कि मैं शायद बुरी तरह से पांडित्यपूर्ण होने के लिए तैयार हो जाऊंगा, लेकिन हज़ारों एनएफएस संस्करणों के साथ मेरी नौकरी में शिकार करने के लिए और सभी प्रकार की खराब-नामित फ़ाइलों के लिए, मैं चाहता हूं कि अधिक लोग पांडित्यपूर्ण होंगे।
जोड़ने के लिए: वास्तविक दुनिया में, मैं updatedb
एक खोज योग्य फ़ाइल इंडेक्स बनाने का उपयोग करना चाह सकता हूं , locate
बजाय find
उस इंडेक्स को पढ़ने के, और थ्रेड के parallel
बजाय xargs
। हालांकि यह इस सवाल के दायरे से बाहर है। मैंने लिखा कि सीधे चेहरे के साथ भी। मुझे इतनी परवाह क्यों है? मैं फिल्म और ऑडियो फाइलों की तलाश में हूं; या कुछ विशेष प्रकार की तस्वीरें; या प्रोजेक्ट डेटा निर्देशिका में बाइनरी निष्पादनयोग्य।
.pdf
, तो आपकी पैदल सेना को बहुत सराहना मिलेगी। लेकिन यह एक अपेक्षाकृत असामान्य स्थिति है (आपकी नौकरी के बावजूद) और हमारे पास यह मानने का कोई कारण नहीं है कि पूछने वाले को वास्तव में इससे निपटना है, इसलिए मुझे लगता है कि आप जिस बिंदु को वैध बना रहे हैं, वह विचलित करने वाला है - और मुझे लगता है कि आपने जिस जोरदार तरीके से इसे दोहराया है, वह उत्तर को "(शायद उपयोगी नहीं)" के दायरे में धकेलता है। (केवल मेरी राय, निश्चित रूप से।)