2011-01-26 11 views
5

मैं (उदाहरण के लिए अब ऑनलाइन नहीं है) commandlinefu.com पर निम्न स्क्रिप्ट मिल गया है:यह बैश कुछ फ़ाइलों को हटाने के लिए कैसे काम करता है लेकिन कुछ फाइलें काम करती हैं?

rmbut() { 
    local x=("[email protected]") 
    IFS=, rm -rf *[!"${x[*]}"] 
} 

यह सभी फ़ाइलों और निर्देशिकाओं लेकिन कमांड लाइन पर नामित लोगों को हटाता है।

आप निम्नलिखित समझा सकते हैं:

  • क्या पहली पंक्ति पर हो रहा है? [email protected] का अर्थ है सभी तर्क, लेकिन यह ब्रांड्स के अंदर क्यों रखा जाता है?
  • मैंने IFS पढ़ा है लेकिन वास्तव में इसका उपयोग कभी नहीं किया है, इसका उपयोग यहां क्या है?
  • *[!"${x[*]}"] के साथ क्या हासिल किया जाता है? मैं समझ नहीं पा रहा हूं कि इसे किसी चीज़ में कैसे विभाजित किया जाए।
+0

क्या आप वाकई "स्थानीय x .." रेखा पर ब्रांड्स() हैं या वे ब्रेसिज़ {} या ब्रैकेट [] हैं। यह एक फर्क पड़ता है। साथ ही, फ़ंक्शन के दिखने से, यह केवल उन सभी फ़ाइलों को हटा रहा है जिन्हें फ़ंक्शन पर पैरामीटर द्वारा निर्दिष्ट बेसनाम (ओं) को छोड़ दिया गया है। – kvista

+0

हां, कोष्ठक सही हैं। यह कार्य का उद्देश्य है, यह स्पष्ट है, मैं जानना चाहता हूं कि क्यों ^^ –

उत्तर

4

local x=("[email protected]") एक सरणी है जो बनाता है सभी तर्कों की एक प्रति ([email protected] स्वयं एक सरणी है)।

IFS=, आंतरिक क्षेत्र विभाजक को अल्पविराम में सेट करता है।

IFS=, rm -rf *[!"${x[*]}"] उन सभी फ़ाइलों को निकालने का कहना है जो तर्क के रूप में पारित किसी भी चरित्र में समाप्त नहीं होते हैं। चूंकि * को सरणी के सूचकांक के रूप में उपयोग किया जाता है और चर को उद्धृत किया जाता है, इसे एक स्ट्रिंग में विस्तारित किया जाता है और रिक्त स्थान जो सामान्य रूप से सरणी के तत्वों को अलग करते हैं उन्हें IFS (इस मामले में एक अल्पविराम) की सामग्री द्वारा प्रतिस्थापित किया जाता है।

rmbut a b c 

rm -rf *[!a,b,c] पर ले कर जो भी फ़ाइलों को एक अल्पविराम में खत्म नहीं निकलेगी।

मैं लगता कार्य करने के लिए सरल किया जा सकता है:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
} 

लेकिन अपने व्यवहार को आसानी से अलग होगा। यह संस्करण IFS को शून्य करने के लिए सेट करता है, इसलिए उपर्युक्त उदाहरण rm -rf *[!abc] को हल करेगा जो एक अल्पविराम में समाप्त होने वाली फ़ाइलों को हटा देगा (एक अल्पविराम को ऐसी फ़ाइलों को संरक्षित करने के लिए एक तर्क के रूप में स्पष्ट रूप से पारित किया जाना होगा)। हालांकि, उस व्यवहार को IFS=, सेट करके वापस किया जा सकता है (सरणी की प्रतिलिपि बनाना आवश्यक नहीं है)।

+0

विस्तृत उत्तर के लिए धन्यवाद :) –

3

# एक सरणी एक्स बनाने के लिए, समारोह
local x=("[email protected]")

# सेट नहीं आईएफएस चर करने के लिए तर्क हैं। यह बनाने डबल उद्धृत सरणियों डब्ल्यू/विभाजक
IFS=

# एक पैटर्न मिलान फ़ाइलों को हटा दें ओ, यानी सरणी से एक चरित्र के साथ समाप्त नहीं एक शब्द का विस्तार एक्स
rm -rf *[!"${x[*]}"]

+0

@ यूजीन वाई: आपने 'आईएफएस =' लिखा है लेकिन मूल 'आईएफएस = है,' क्या आपने टाइपो या कॉमा बनाया है लाइन की दूसरी सामग्री से 'आईएफएस' को अलग करने के लिए? –

+0

@ यूजीन वाई: क्या आप निश्चित हैं? मैंने अभी अभी कोशिश की है, commandlinefu.com से चिपकाया गया कॉपी और यह काम करता है ... –

+0

@Alberto: 'touch abc bcd cde; rmbut bcd # केवल "cde" को हटाता है ' –

संबंधित मुद्दे