2011-09-24 89 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