以下是我所拥有的:
- SQLite 数据库
main.db
- 一组包含 10,000 个 HTML 文件,分别名为
1.html
、2.html
、3.html
...10000.html
。
main.db 有一个包含两列的表:
id | name
1 | apple
2 | banana
3 | peach
...
10000 | orange
我需要在每个 html 文件的开头插入由其 id 引用的名称的文本,如以下示例:
旧1.html:
<body>body content, text etc</body>
所需1.html:
<title>apple</title><body>body content, text etc</body>
批量前置的首选方法是什么?
答案1
像这样:
# setup example database
sqlite3 main.db 'CREATE TABLE files(id INTEGER, name STRING)'
sqlite3 main.db 'INSERT INTO files(id, name) VALUES(1, "apple")'
sqlite3 main.db 'INSERT INTO files(id, name) VALUES(2, "banana")'
sqlite3 main.db 'INSERT INTO files(id, name) VALUES(3, "peach")'
sqlite3 main.db 'INSERT INTO files(id, name) VALUES(10000, "orange")'
# setup example input files
echo '<body>body content, text etc</body>' \
| tee 1.html 2.html 3.html 10000.html \
> /dev/null
# show original content of example files
tail *.html
# fixup files "in-place"
while IFS='|' read id name; do
filename="${id}.html"
( echo -n "<title>${name}</title>"; cat "${filename}" ) | sponge "${filename}"
done < <( sqlite3 main.db 'SELECT id,name FROM files' )
# show final content of example files
tail *.html
这里我们使用以下技术:
sponge
- 将读取所有输入,然后将数据写入文件名,以争论(不是使用 shell 重定向,因为这会在打开时截断文件)IFS='|' read id name
- 默认情况下,sqlite3
每行将报告一条记录,并使用管道字符 (|
) 作为字段分隔符来分隔列。- 如果记录数据中报告了换行符,则会出现问题。
- 请注意才不是字段值中的转义管道字符,因此带有 的记录
id=10000, name="ora|nge"
将被报告为10000|ora|nge
。 - 在这种情况下,第一个字段(
10000
)被分配给${id}
,并且所有剩余的字段(ora
和nge
)被分配给${name}
,并且分隔符保持完整(即ora|nge
:),所以您没问题......但是,如果您添加字段或对它们进行重新排序,您可能会受到影响。
如果您需要处理换行符或管道字符之类的内容,那么您可以:
- 遍历 ID,逐个调用您感兴趣的特定字段,一次一条记录
- 编写一个小的 Python 脚本或类似程序来更安全、更快地完成此操作:
import sqlite3
conn = sqlite3.connect('main.db')
for id, name in conn.execute('SELECT id,name FROM files'):
with open(f'{id}.html', 'r+') as f:
data = f.read()
f.seek(0)
f.write(f'<title>{name}</title>{data}')