将字符串、文件内容、字符串通过管道传输到 SQLite 中,而无需中间文件?

gla*_*con 1 sqlite bash shell pipe

我有这个 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
Run Code Online (Sandbox Code Playgroud)

我想改进这一点,以便不生成中间文件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
Run Code Online (Sandbox Code Playgroud)

Léa*_*ris 5

要么组命令并将整个组重定向到管道到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"
Run Code Online (Sandbox Code Playgroud)

使用此处文档作为输入sqlite3

sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error" <<EOF
BEGIN TRANSACTION
$(cat "$file_name_original_sql")
COMMIT;
EOF
Run Code Online (Sandbox Code Playgroud)

或者用于printf组合通过管道传输到的元素sqlite3

printf 'BEGIN TRANSACTION;\n%sCOMMIT;\n' "$(cat "$file_name_original_sql")" |
  sqlite3 "$file_name_sqlite_db" 2> "$path_to_insert_error"
Run Code Online (Sandbox Code Playgroud)

或者创建一个函数将 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"
Run Code Online (Sandbox Code Playgroud)