SQLite:如何同时从标准输入读取数据并从变量读取表名?

问题描述 投票:0回答:3

在 bash 中,我想将我的 TSV 表从 stdin 传递给 sqlite3,同时还传递要从变量导入的表的名称。如何才能做到这一点?例如:

#!/bin/bash

output_sql_db="$1"
input_tsv="$2"
table_name="$3

tail -n +2 "$input_tsv" | sqlite3 "$output_sql_db" '.import "/dev/stdin" ${table_name}'

当然,在此示例中,由于在 sqlite3 命令中使用了

${table_name}
,因此
'
未正确扩展。这应该怎么做呢?看来我找到的所有答案都只能显示手动处理其中一个(数据导入或传递表名称)。

bash sqlite
3个回答
1
投票

使用 bash 定界文档,并决定何时/何处转义输入。在变量定义或命令创建时。

编辑:

我的观点是将您正在使用的语法/方法简化为类似的东西。

output_sql_db="$1"
input_tsv="$2"
table_name="$3
importfile=$(tail -n +2 $input_tsv)
sqlite3 "$output_sql_db .import ${importfile} ${table_name}"

1
投票

示例中的主要问题是在命令周围使用单引号,这会阻止变量插值。如果要使用变量,需要使用双引号。

另一个(不相关的)可能的问题是您对

tail -n +2
的使用。如果您想要的是 $input_tsv 文件的最后 2 行,则正确的语法是
tail -2 $input_tsv

最后,您的

$input_tsv
变量的名称表明您的输入是制表符分隔的。如果是这种情况,您需要告诉 sqlite 您不使用它的默认分隔符
|
而是使用 Tab 字符,在 Bash 中可以写为
$'\t'

所以这个重写版本的脚本应该可以工作:

#!/bin/bash

output_sql_db="$1"
input_tsv="$2"
table_name="$3

tail -2 "$input_tsv" | sqlite3 -separator $'\t' "$output_sql_db" ".import /dev/stdin $table_name"

0
投票

使用 Bash 过程替换SQLite 3.44.0 将 CSV 文件导入到 SQLite 数据库表中:

#!/bin/bash

# Uncomment to enable statement tracing.
#set -o xtrace

output_sql_db="$1"
input_tsv="$2"
table_name="$3"

# Check whether the table exists in the database.
table_exists="$(sqlite3 $output_sql_db << SQL
  SELECT name
  FROM sqlite_master
  WHERE type = 'table'
    AND name = '$table_name';
SQL
)"

if [ "$table_exists" == "$table_name" ]
then
  skip_count="1"
else
  skip_count="0"
fi

cat "$input_tsv" |
  sqlite3 "$output_sql_db" ".import --csv --skip $skip_count "<(cat)" $table_name"

请注意,我将

/dev/stdin
替换为进程替换
<(cat)

如果

--csv
是制表符分隔文件,请将
--ascii
更改为
$input_tsv

© www.soinside.com 2019 - 2024. All rights reserved.