inotify和bash

inotify和bash,bash,inotify,Bash,Inotify,我正在尝试使用inotify工具创建一个bash脚本,它将监视一个目录,并通过删除包含“EE”的行来更改所有新文件。一旦更改,它会将文件移动到另一个目录 #!/bin/sh while inotifywait -e create /home/inventory/initcsv; do sed '/^\"EE/d' Filein > fileout #how to capture File name? mv fileout /home/inventor

我正在尝试使用inotify工具创建一个bash脚本,它将监视一个目录,并通过删除包含“EE”的行来更改所有新文件。一旦更改,它会将文件移动到另一个目录

    #!/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

请提供帮助?

默认情况下,inotifywait-e CREATE的文本输出格式为

     watched_filename CREATE event_filename
其中,
wasted_filename
表示
/home/inventory/initcsv
event_filename
表示新文件的名称

因此,在inotifywait-e…行中,替换您的
,放置:

    DIR=/home/inventory/initcsv
    while RES=$(inotifywait -e create $DIR); do
        F=${RES#?*CREATE }
在您的
sed
行中,使用
$F
作为
文件名。注意,
$(…)
构造是posix兼容的进程替换形式(通常使用反勾号完成),并且
${RES#pattern}
结果等于
$RES
,删除了最短的模式匹配前缀。请注意,图案的最后一个字符为空白。[见更新2]

更新1要处理可能包含空格的文件名,请在sed行中使用
“$F”
而不是
$F
。也就是说,在对
F
的值的引用周围使用双引号

RES=…
F=…
定义不需要使用双引号,但如果您愿意,可以使用双引号;例如:
F=${RES#?*CREATE}
F=“${RES#?*CREATE}”
在处理包含空格的文件名时,这两种方法都可以正常工作

更新2如Daan评论中所述,
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.

引用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.
换句话说,它将文件名打印到标准输出。所以,您需要从标准输出中读取它们,并对它们进行操作以完成您想要做的事情

的输出形式如下:

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用于使用-m开关。如果不保持监视更改,脚本将不会处理在处理上一个文件时上载的任何文件。为什么不使用
--format%w
选项输出,以便只能使用文件名?@Daan,是的,这是有意义的(使用%f,而不是%w)。请参阅更新2
inotifywait-e delete\u self aSymlinkFilename
在删除符号链接时不起作用,仅当其真实文件被删除时才起作用:(,在断开的符号链接上也不起作用:(
fi
是否错误?是的,我认为应该
完成
)。