web-dev-qa-db-ja.com

inotifyとbash

ディレクトリを監視し、「EE」を含む行を削除してすべての新しいファイルを変更するinotify-toolsで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

助けてください?

25
user963091

デフォルトでは、_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 }
_

sed行では、Fileinの名前として_$F_を使用します。 $(...)構造は、posix互換のプロセス置換形式(多くの場合、バックティックを使用して行われます)であり、_${RES#pattern}_の結果は_$RES_と等しく、最短のパターンマッチングプレフィックスが削除されています。パターンの最後の文字は空白であることに注意してください。 [更新2を参照]

pdate 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
_

1つの端末とコマンドで実行

_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.
_
22

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
12

Inotifywaitのmanページを引用すると:

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.

つまり、ファイルの名前を標準出力に出力します。したがって、標準出力からそれらを読み取り、実行して、実行したいことを実行する必要があります。

1
bmargulies