管道字符串,文件内容,字符串到SQLite没有中间文件



我有一个shell脚本,它接受一组INSERT语句,并在开头放一个"BEGIN TRANSACTION",在结尾放一个"COMMIT"。INSERT语句有很多,因此这使得插入速度更快。

我成功使用的脚本如下:

file_name_improved_sql=foo-improved.sql
file_name_original_sql=foo.sql
file_name_sqlite_db=bar.db
path_to_insert_error=/tmp/fooerrors.log
#
echo 'BEGIN TRANSACTION;' | cat - $file_name_original_sql  > $file_name_improved_sql
echo "COMMIT;" >> $file_name_improved_sql
#
cat $file_name_improved_sql | sqlite3 $file_name_sqlite_db 2> $path_to_insert_error

我想改进一下,这样就可以直接通过管道输入两个字符串和文件的内容,而不是生成中间文件file_name_improved_sql

像这样的东西(除了这个不起作用(。。。

export string1="BEGIN TRANSACTION"
export string2="COMMIT"
cat $string1 $file_name_improved_sql $string2 | sqlite3 $file_name_sqlite_db 2> $path_to_insert_error

任一组命令并将整个组重定向到管道sqlite3:

{
printf %s\n 'BEGIN TRANSACTION;'
cat "$file_name_original_sql"
printf %s\n 'COMMIT;'
} | sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error"

使用此处文档作为sqlite3:的输入

sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error" <<EOF
BEGIN TRANSACTION
$(cat "$file_name_original_sql")
COMMIT;
EOF

或者使用printf组合管道连接到sqlite3:的元素

printf 'BEGIN TRANSACTION;n%sCOMMIT;n' "$(cat "$file_name_original_sql")" |
sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error"

或者创建一个函数将SQL输入流框化成事务:

sql_transaction() {
printf %s\n 'BEGIN TRANSACTION;'
cat
printf %s\n 'COMMIT;'
}
sql_transaction <"$file_name_original_sql" |
sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error"

sqlite3shell中的.read命令采用一个文件名来读取命令。如果该名称以管道字符开头,它将被视为shell命令而不是文件名,并从该命令的标准输出中读取。

所以你可以做一些类似的事情

sqlite3 "$file_name_sqlite_db" ".read '|echo "BEGIN TRANSACTION;"; cat "file_name_original_sql"; echo "COMMIT;"'"

使用heredoc有助于简化报价:

sqlite3 "$file_name_sqlite.db" <<EOF
.read '|echo "BEGIN TRANSACTION;"; cat "$file_name_original.sql"; echo "COMMIT;"'
EOF

相关内容

  • 没有找到相关文章

最新更新