29

I am trying to make a bash script with inotify-tools that will monitor a directory and alter all new files by removing lines containing "EE". Once altered it will move the files to another directory

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

Please help?

DNA
  • 40,109
  • 12
  • 96
  • 136
user963091
  • 347
  • 1
  • 3
  • 8

3 Answers3

25

By default, the text output from inotifywait -e CREATE is of form

     watched_filename CREATE event_filename

where watched_filename represents /home/inventory/initcsv and event_filename represents the name of the new file.

So, in place of your while inotifywait -e ... line, put:

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

and in your sed line use $F as the Filein name. Note, the $(...) construction is posix-compatible form of process substitution (often done using backticks) and the ${RES#pattern} result is equal to $RES with the shortest pattern-matching prefix removed. Note, the last character of the pattern is a blank. [See update 2]

Update 1 To handle file names that may contain whitespace, in the sed line use "$F" instead of $F. That is, use double quotes around the reference to value of F.

The RES=... and F=... definitions do not need to use double quotes, but it is ok to use them if you like; for example: F=${RES#?*CREATE } and F="${RES#?*CREATE }" both will work ok when handling filenames containing whitespace.

Update 2 As noted in Daan's comment, inotifywait has a --format parameter that controls the form of its output. With command

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

running in one terminal and command

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

running in another terminal, the following output appeared in the first terminal:

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.
James Waldby - jwpat7
  • 8,060
  • 2
  • 19
  • 35
13

The output from inotifywait is of the form:

filename eventlist [eventfilename]

If your file names can contain spaces and commas, this gets tricky to parse. If it only contains 'sane' file names, then you can do:

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
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
  • 1
    +1 for using the -m switch. If you do not keep monitoring for changes, the script will not process any file that is uploaded while the previous file is being processed. – frnknstn May 02 '13 at 15:37
1

Quoting the man page of 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.

In other words, it prints the names of the files to standard output. So, you need to read them from standard output and operate on them to do what you want to do.

bmargulies
  • 91,317
  • 38
  • 166
  • 290