जवाबों:
यहाँ एक POSIX समाधान है जिसे समझने के लिए बहुत सरल होना चाहिए:
find . -type f -exec awk -v x=10 'NR==x{exit 1}' {} \; -exec echo rm -f {} \;
स्टीफन के जवाब के रूप में , echoजब हटा दिया जाएगा के साथ खुश को हटा दें।
डॉट .वर्तमान निर्देशिका का प्रतिनिधित्व करता है। findफ़ाइलों और निर्देशिकाओं को पुनरावर्ती पाता है ., और उनके साथ काम कर सकता है।
-typeमें से एक है findके प्राइमरी ; यह एक परीक्षण है जो प्रत्येक फ़ाइल और निर्देशिका के लिए किया जाएगा जो पुनरावर्ती रूप से (भीतर .) पाया जाता है , और लाइन पर बाकी प्राइमरी का मूल्यांकन केवल तभी किया जाता है यदि यह "सही" है।
इस विशेष मामले में, हम केवल तभी जारी रखते हैं जब हम एक नियमित फ़ाइल के साथ काम कर रहे होते हैं , न कि कोई निर्देशिका या कुछ और (जैसे एक ब्लॉक डिवाइस।)।
-execप्राथमिक (के find) एक बाहरी आदेश कहता है, और उसे अगले प्राथमिक के लिए आगे बढ़ता है, तो बाहरी कमांड बाहर निकलता है सफलतापूर्वक ( "0" के निकास की स्थिति)। {}फ़ाइल नाम से "माना" किया जा रहा साथ बदल दिया है findआदेश। इसलिए पहली -execकॉल निम्न शेल कमांड के बराबर है, जिसे बदले में प्रत्येक फ़ाइल के लिए निष्पादित किया गया है:
awk -v x=10 'NR==x{exit 1}' ./somefilename
Awk अपने आप में एक संपूर्ण भाषा है, जिसे CSV जैसी सीमांकित पाठ फ़ाइलों को संभालने के लिए डिज़ाइन किया गया है। Awk सशर्तियां और आदेश (जो एकल उद्धरणों के बीच और अक्षरों से शुरू NRहोते हैं) को पाठ फ़ाइल की प्रत्येक पंक्ति के लिए निष्पादित किया जाता है। (स्पष्ट लूपिंग।)
Awk को पूरी तरह से जानने के लिए, मैं Grymoire Tutorial की सिफारिश करता हूं , लेकिन मैं ऊपर दिए गए कमांड में इस्तेमाल किए गए Awk फीचर्स के बारे में बताऊंगा ।
-vAwk करने के लिए ध्वज हमारे सामने Awk आदेश (फ़ाइल की प्रत्येक पंक्ति के लिए।) क्रियान्वित कर रहे हैं इस मामले में हम सेट में एक Awk चर (एक बार) स्थापित करने के लिए अनुमति देता है xके लिए 10।
NRएक विशेष अर्क चर है जिसका उल्लेख " वर्तमान आर इकोर्ड के एन umber " है। दूसरे शब्दों में, यह वह पंक्ति संख्या है जिसे हम लूप के माध्यम से किसी विशेष पास में देख रहे हैं।
(ध्यान दें कि यह है संभव है, हालांकि असामान्य, एक अलग "का उपयोग करने आर ecord एस , eparator" एक नई पंक्ति चरित्र के डिफ़ॉल्ट से सेटिंग से RS। यहाँ रिकॉर्ड विभाजक के साथ खेल का एक उदाहरण है। )
सामान्य रूप से स्थितियाँ ( कार्य घुंघराले ब्रेसिज़ के बाहर) (समान रूप से ब्रेसिज़ के अंदर ) में अवाक स्क्रिप्ट्स होती हैं। यौगिक स्थितियाँ और यौगिक क्रियाएं हो सकती हैं, और एक डिफ़ॉल्ट स्थिति (सत्य) और एक डिफ़ॉल्ट क्रिया (प्रिंट) होती है, लेकिन हमें इसकी आवश्यकता है 'उन लोगों के साथ परेशान नहीं है।
यहां शर्त है, "क्या यह 10 वीं पंक्ति है?" यदि यह मामला है, तो हम एक गैर-शून्य निकास स्थिति के साथ बाहर निकलते हैं, जो शेल स्क्रिप्टिंग में "असफल कमांड समाप्ति" का अर्थ है।
इस प्रकार यह एकमात्र आदेश सफलतापूर्वक बाहर निकल जाएगा यदि फ़ाइल का अंत 10 वीं पंक्ति तक पहुंचने से पहले पहुंच जाता है।
इसलिए यदि Awk स्क्रिप्ट सफलतापूर्वक बाहर निकलती है, तो इसका मतलब है कि आपके पास दस लाइनों से कम की फ़ाइल है।
अगली -execकॉल (यदि आप हटाते हैं echo) प्रत्येक फ़ाइल (जो कि findप्राइमरी के मूल्यांकन में उस तक जाती है) को हटाकर हटा देगी :
rm -f ./somefilename
एक findकार्यान्वयन मान लें जो -readableविधेय का समर्थन करता है (यदि आपका findसमर्थन नहीं करता है, तो बस इसे हटा दें, आपको बस गैर-पठनीय फ़ाइलों के लिए त्रुटि संदेश मिलेगा, या इसके साथ प्रतिस्थापित करें -exec test -r {} \;):
x=10 find . -type f -readable -exec sh -c '
for file do
lines=$(wc -l < "$file") && [ "$((lines))" -lt "$x" ] && echo rm -f "$file"
done' sh {} +
echoअगर खुश है तो निकाल दो ।
यह विशेष रूप से कुशल नहीं है कि यह हर फ़ाइल में सभी पंक्तियों को गिनता है जबकि इसे केवल xवें एक पर रोकने की आवश्यकता होती है और यह प्रत्येक फ़ाइल के लिए एक wc(और संभवतः एक rm) कमांड चलाता है ।
GNU के साथ awk, आप इसे और अधिक कुशल बना सकते हैं:
x=10
find . -type f -readable -exec awk -v x="$x" -v ORS='\0' '
FNR == x {nextfile}
ENDFILE {if (FNR < x) print FILENAME}' {} +|
xargs -r0 echo rm -f
(फिर, echoखुश होने पर हटा दें )।
उसी के साथ perl:
x=10 find . -type f -readable -exec perl -Tlne '
if ($. == $ENV{x}) {close ARGV}
elsif (eof) {print $ARGV; close ARGV}' {} +
बदलें printके साथ unlinkखुश हैं।
shवह है जो उस इनलाइन स्क्रिप्ट में जाता है $0, उदाहरण के लिए त्रुटि संदेशों के लिए उपयोग किया जाता है। wc -l "$file"फ़ाइल का नाम जो हम यहां नहीं चाहते हैं और प्रिंट करेंगे wcभले ही फ़ाइल को खोला न जा सके। $xको निर्यात किया जाता है find( x=10 find...) जो खुद इसे पास करता है sh।
find: -readable: unknown primary or operator।
bash। bashकेवल एक कमांड-लाइन दुभाषिया है, लेकिन findकार्यान्वयन का। -readableएक GNU एक्सटेंशन है, जो OS / X में उपलब्ध नहीं है find। इसका उपयोग केवल उन फ़ाइलों तक सीमित करने के लिए किया जाता है जो पठनीय हैं (आप गैर-पठनीय फ़ाइलों के लिए लाइन की गिनती प्राप्त करने में सक्षम नहीं होंगे)। आप इसे पहले एक के लिए छोड़ सकते हैं, फिर आप केवल wcपढ़ने योग्य फ़ाइलों के लिए फ़ाइलें खोलते समय त्रुटि संदेश प्राप्त कर सकते हैं।
पूर्णता के लिए, एक तरफ AWK आप एक ही परिणाम प्राप्त करने के लिए GNU sed का उपयोग कर सकते हैं:
find . -type f -exec sed 11q1 '{}' ';' -exec echo rm -f '{}' ';'
जिसके परिणामस्वरूप थोड़ी अधिक संक्षिप्त कमांड लाइन होती है।
व्याख्या
11 - is the address, i.e. "the eleventh line"
q - is for _q_uit (abort the execution)
1 - is the exit code parameter for q (GNU sed extension)
sh? 2.wc -l < "$file"से तेज हैwc -l "$file"? 3. श का मूल्य कैसे पता चलता है$x, जिसे कॉल बैश शेल में परिभाषित किया गया है?