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美元引用,因此您不必担心字符串中的单引号。您必须转义 shell 中的$字符以删除其在 shell 中的特殊含义。
    对美元引号使用“不可能”字符串,因此它不能出现在字符串中。如果您没有,您可以测试引号字符串并在不太可能的情况下更改它应该匹配,以绝对确定。

  • 用于SELECT .. WHERE NOT EXISTSINSERT 以自动防止重新插入已经存在的条目。这可以完全防止表中的重复条目 - 不仅仅是在新条目中。

  • 上的索引movies.movie(可能,但不一定是唯一的)会加快插入速度。

于 2012-06-29T23:06:14.580 回答
0

为什么要打扰grepsed不是让数据库检测重复项?

movie在每次运行时添加唯一索引并创建一个新的(临时)插入脚本,然后使用自动提交(默认)或-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 $@/$#

然后最简单的 adder.sh脚本没有任何参数检查:

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

您可以在一个目录中拥有数千个文件,并且您可以使用原始脚本来解决问题。

于 2012-07-03T22:06:01.473 回答