2

ディレクトリを一覧表示し、これらのディレクトリを挿入するための SQL スクリプトを作成するスクリプトを作成しようとしています。問題は、新しいディレクトリを挿入したいだけです。

#If file doesn't exist add the search path test
if [ ! -e  /home/aydin/movies.sql ] 
then
    echo "SET SEARCH_PATH TO noti_test;" >> /home/aydin/movies.sql;
fi
cd /media/htpc/
for i in *
do
    #for each directory escape any single quotes
    movie=$(echo $i | sed "s:':\\\':g" )
    #build sql insert string
    insertString="INSERT INTO movies (movie) VALUES (E'$movie');";
    #if sql string exists in file already   
    if grep -Fxq "$insertString" /home/aydin/movies.sql
    then
        #comment out string
        sed -i "s/$insertString/--$insertString/g" /home/aydin/movies.sql
    else
        #add sql string
            echo $insertString >> /home/aydin/movies.sql;
    fi
done;
#execute script
psql -U "aydin.hassan" -d "aydin_1.0" -f /home/aydin/movies.sql;

スクリプトは一重引用符を含むエントリを認識しないため、新しいディレクトリなしでスクリプトを再度実行すると、ファイルは次のようになります。

--INSERT INTO movies (movie) VALUES (E'007, Moonraker (1979)');
--INSERT INTO movies (movie) VALUES (E'007, Octopussy (1983)');
INSERT INTO movies (movie) VALUES (E'007, On Her Majesty\'s Secret Service (1969)');  

これを行うためのより良い方法についても提案を受け付けています。私のプロセスはかなり長く、非効率的です:)

4

3 に答える 3

1

スクリプトは一般的に私には良さそうです。改訂版 (未テスト) を検討してください。

#! /bin/bash
#If file doesn't exist add the search path test
if [ ! -e  /home/aydin/movies.sql ] 
then
    echo 'SET search_path=noti_test;' > /home/aydin/movies.sql;
fi
cd /media/htpc/
for i in *
do
    #build sql insert string - single quotes work fine inside dollar-quoting
    insertString="INSERT INTO movies (movie) SELECT \$x\$$movie\$x\$
WHERE NOT EXISTS (SELECT 1 FROM movies WHERE movie = \$x\$$movie\$x\$);"

    #no need for grep. SQL is self-contained.
    echo $insertString >> /home/aydin/movies.sql
done

#execute script
psql -U "aydin.hassan" -d "aydin_1.0" -f /home/aydin/movies.sql;
  • 新しいファイルを開始するには、>代わりに使用します>>

  • '展開する変数のない文字列定数には一重引用符を使用します

  • 文字列内の単一引用符について心配する必要がないように、PostgreSQLのドル引用符を使用します。$シェルでの特別な意味を削除するには、シェルで文字をエスケープする必要があります。
    ドル引用符には「不可能な」文字列を使用して、文字列に表示されないようにします。持っていない場合は、引用文字列をテストし、一致する可能性が低い場合にそれを変更して、絶対に確実にすることができます。

  • INSERT に使用SELECT .. WHERE NOT EXISTSして、既存のエントリが再挿入されるのを自動的に防ぎます。これにより、新しいエントリ間だけでなく、テーブル内のエントリの重複が完全に防止されます。

  • movies.movie(UNIQUE である可能性がありますが、必ずしも UNIQUE であるとは限りません)のインデックスは、INSERT を高速化します。

于 2012-06-29T23:06:14.580 に答える
0

データベースに重複を検出させるだけでなく、わざわざとを気にするのはなぜgrepですか?sed

に一意のインデックスを追加し、movie実行ごとに新しい(一時的な)挿入スクリプトを作成してから、autocommit(デフォルト)または-v ON_ERROR_ROLLBACK=1オプションを使用して実行しますpsql--column-inserts映画データベースの完全な挿入スクリプトを取得するには、オプションを指定してダンプしますpg_dump

お役に立てれば。

于 2012-06-29T23:08:30.233 に答える
0

incronと呼ばれるユーティリティデーモンがあり、監視対象のディレクトリにファイルが書き込まれるたびにスクリプトを起動します。カーネル イベントを使用し、ループは使用しません - Linux のみ。

その構成 (完全なファイル パス) で:

/media/htpc IN_CLOSE_WRITE /home/aydin/added.sh $@/$#

次に、param チェックのない最も単純なadder.shスクリプト:

#!/bin/bash
cat <<-EOsql | psql -U "aydin.hassan" -d "aydin_1.0"
INSERT INTO movies (movie) VALUES (E'$1');
EOsql

元のスクリプトに直面する可能性があるため、1 つのディレクトリに何千ものファイルを格納できますが、問題はありません。

于 2012-07-03T22:06:01.473 に答える