2011-09-24 10 views
19

मैं इनोटिफ़-टूल्स के साथ एक बैश स्क्रिप्ट बनाने की कोशिश कर रहा हूं जो निर्देशिका की निगरानी करेगा और "ईई" वाली रेखाओं को हटाकर सभी नई फ़ाइलों को बदल देगा। एक बार बदल दिया यह एक और निर्देशिकाinotify और bash

#!/bin/sh 
    while inotifywait -e create /home/inventory/initcsv; do 
     sed '/^\"EE/d' Filein > fileout #how to capture File name? 
     mv fileout /home/inventory/csvstorage 
    fi 
    done 

लिए फ़ाइलों को स्थानांतरित देगा मदद?

उत्तर

18

डिफ़ॉल्ट रूप से, inotifywait -e CREATE से पाठ उत्पादन

 watched_filename CREATE event_filename 

जहां watched_filename का प्रतिनिधित्व करता है /home/inventory/initcsv और event_filename नया फ़ाइल का नाम का प्रतिनिधित्व करता है फार्म की है।

तो, अपने while inotifywait -e ... लाइन के स्थान पर, डाल:

DIR=/home/inventory/initcsv 
    while RES=$(inotifywait -e create $DIR); do 
     F=${RES#?*CREATE } 

और Filein नाम के रूप में अपने sed लाइन उपयोग $F में। नोट, $(...) निर्माण प्रक्रिया प्रतिस्थापन (अक्सर बैकटिक्स का उपयोग करके किया जाता है) का पॉज़िक्स-संगत रूप है और ${RES#pattern} परिणाम $RES के बराबर है जो सबसे कम पैटर्न-मिलान उपसर्ग हटा दिया गया है। नोट, पैटर्न का अंतिम चरित्र एक खाली है।

अद्यतन 1 sed लाइन उपयोग $F के बजाय "$F" में फ़ाइल नाम है कि खाली स्थान के हो सकते हैं, को संभालने के लिए [अद्यतन 2 देखें]। यही है, F के मान के संदर्भ में डबल कोट्स का उपयोग करें।

RES=... और F=... परिभाषाओं को डबल कोट्स का उपयोग करने की आवश्यकता नहीं है, लेकिन यदि आप चाहें तो उनका उपयोग करना ठीक है; उदाहरण के लिए: F=${RES#?*CREATE } और F="${RES#?*CREATE }" व्हाइटसाइट युक्त फ़ाइल नामों को संभालने पर दोनों ठीक काम करेंगे।

अद्यतन 2 के रूप में दान की इस टिप्पणी में बताया गया है, inotifywait एक --format पैरामीटर है कि इसके उत्पादन के रूप को नियंत्रित करता है।

Setting up watches. 
Watches established. 
RES is a at Tue Dec 31 11:37:20 MST 2013 
Setting up watches. 
Watches established. 
RES is aaa at Tue Dec 31 11:37:21 MST 2013 
Setting up watches. 
Watches established. 
RES is aaaa at Tue Dec 31 11:37:22 MST 2013 
Setting up watches. 
Watches established. 
+0

क्यों न केवल '--format% w' विकल्प का उपयोग करके आउटपुट क्यों करें, इसलिए केवल फ़ाइल नाम का उपयोग किया जा सकता है? – Daan

+0

@Daan, हाँ, यह समझ में आता है (% f के साथ,% w नहीं)। अद्यतन 2 –

+0

'inotifywait -e delete_self aSymlinkFilename' अभ्यस्त काम अगर सिमलिंक हटा दी जाती है, केवल तभी जब इसकी वास्तविक फ़ाइल हटा दी जाती है :(देखें, यह टूटा हुआ सिमलिंक :( –

1

inotifywait मैन ऑफ द पेज का हवाला देते हुए: आदेश के साथ

while RES=$(inotifywait -e create $DIR --format %f .) 
    do echo RES is $RES at `date`; done 

एक टर्मिनल और कमांड

touch a aa; sleep 1; touch aaa;sleep 1; touch aaaa 

में चल रहे एक और टर्मिनल में चल रहा है, तो निम्न उत्पादन पहले टर्मिनल में प्रकाशित हुई:

inotifywait will output diagnostic information on standard error and event information on 
    standard output. The event output can be configured, but by default it consists of lines 
    of the following form: 

    watched_filename EVENT_NAMES event_filename 

    watched_filename 
      is the name of the file on which the event occurred. If the file is a directory, a 
      trailing slash is output. 

दूसरे शब्दों में, यह मानक आउटपुट में फ़ाइलों के नाम प्रिंट करता है। इसलिए, आपको उन्हें मानक आउटपुट से पढ़ने और उन पर काम करने की आवश्यकता है जो आप करना चाहते हैं।

8

inotifywait से उत्पादन फार्म की है: अपने फ़ाइल नाम रिक्त स्थान और अल्पविराम कर सकते हैं

filename eventlist [eventfilename] 

हैं, तो यह पार्स करने के लिए मुश्किल हो जाता है।यदि इसमें केवल 'sane' फ़ाइल नाम हैं, तो आप यह कर सकते हैं:

srcdir=/home/inventory/initcsv 
tgtdir=/home/inventory/csvstorage 
inotifywait -m -e create "$directory" | 
while read filename eventlist eventfile 
do 
    sed '/^"EE/d'/' "$srcdir/$eventfile" > "$tgtdir/$eventfile" && 
    rm -f "$srcdir/$eventfile 
done 
+1

+1 -m स्विच का उपयोग करने के लिए पर भी अभ्यस्त काम करते हैं। यदि आप परिवर्तन के लिए निगरानी नहीं रखते, स्क्रिप्ट, जबकि पिछले फ़ाइल संसाधित किया जा रहा है अपलोड की गई है कि किसी भी फाइल धन्यवाद पर कार्रवाई करेंगे नहीं। – frnknstn

+0

यह वास्तव में एक अच्छा समाधान है,! – sleepycal