2011-09-24 30 views
19

我正在嘗試使用inotify工具創建一個bash腳本,該工具將監視一個目錄並通過刪除包含「EE」的行來更改所有新文件。一旦改變它將文件移動到另一個目錄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/initcsvevent_filename表示新文件的名稱。

所以,在你的地方線while inotifywait -e ...,放:

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

,並在您sed線使用$F作爲Filein名。請注意,$(...)構造是過程替換的posix兼容形式(通常使用反引號完成),${RES#pattern}結果等於$RES,並刪除了最短的模式匹配前綴。請注意,該模式的最後一個字符是空白。 [見更新2]

更新1爲了處理在sed的線使用"$F"代替$F可能包含空白的文件名。也就是說,在參考值F周圍使用雙引號。

RES=...F=...定義不需要使用雙引號,但可以使用它們,如果你喜歡的話;例如:F=${RES#?*CREATE }F="${RES#?*CREATE }"在處理包含空格的文件名時都可以正常工作。

更新2正如大安的評論中指出的,inotifywait有一個--format參數來控制其輸出的形式。隨着命令

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 

運行在另一個終端上運行,以下輸出出現在第一終端:

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

@達安,是的,這是有道理的(%f,而不是%w)。查看更新2 –

+0

'inotifywait -e delete_self aSymlinkFilename'不會工作,如果符號鏈接被刪除,只有當它的真實文件被刪除:(,它也不會工作在破損的符號鏈接:( –

1

引用inotifywait的手冊頁:

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] 

如果你的文件名可以包含空格和逗號,這得到棘手解析。如果它只包含'理智'的文件名,那麼你可以這樣做:

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