我有一个文件:
$cat file1.txt
1234|W
1345|S
8427|D
2132|C
3243|V
我的 sql 文件是:
$cat select.sql
SELECT *
FROM CUSTOMERS
WHERE ID IN (FLAG);
我有一个带有以下说明的外壳
$cat replace.ksh
!#/bin/ksh
S_ids=`awk -F"|" '{print "\47" $1 "\47" ","}' file1.txt |sed '$s/,$//'`
sed -i "s/FLAG/${S_ids}/g" select.sql
我需要将变量“S_ids”的值放入select.sql
字 FLAG 的文件输入中,结果必须为:
$cat select.sql
SELECT *
FROM CUSTOMERS
WHERE ID IN ('1234',
'1345',
'8427',
'2132',
'3243');
我已经尝试过sed -i "s/FLAG/${S_ids}/g" select.sql
,但没有得到预期的结果。
答案1
这不起作用的原因可以从错误消息(您省略提供)推断出来:
sed: -e expression #1, char 14: unterminated `s' command
该sed
命令不接受多行值。您必须将多行折叠成一行。您可以使用如下脚本来完成此操作:
#!/bin/ksh
S_ids="'$(cut -d'|' -f1 file1.txt | tr '\n' ' ' | sed -e 's/ *$//' -e "s/ /','/g")'"
sed -i "s/FLAG/${S_ids}/g" select.sql
要查看如何S_ids
生成,您可以获取管道的每一部分
cut -d'|' -f1 file.txt # Extract first column
tr '\n' ' ' # Convert newlines to spaces
sed -e 's/ *$//' # Strip the trailing space
sed -e "s/ /','/g" # Replace each remaining space with the three characters ','
答案2
#! /bin/ksh
inputfile='file1.txt'
sqlfile='select.sql'
S_ids=$(awk -F"|" '{gsub(/^|$/,"\\'\''",$1) ; print $1","}' "$inputfile" |
xargs |
sed -e 's/,$//')
sed -i "s/FLAG/${S_ids}/g" "$sqlfile"
输出:
$ cat select.sql
SELECT *
FROM CUSTOMERS
WHERE ID IN ('1234', '1345', '8427', '2132', '3243');
这使用 的awk
函数在每行第一个字段的开头和结尾处gsub()
添加。它不仅仅是添加,而是使单引号在管道中保留下来。\'
\',
\'
'
xargs
请注意使用 来'\''
在单引号脚本中嵌入单引号awk
- 将其读作“end-single-quote, escaped-single-quote, start-single-quote-again”。
xargs
默认没有要运行的命令,xargs echo
以便将所有输出行(file1.txt 的单引号第一个字段)放在一行上,并用空格分隔。这将起作用,除非有数以万计的行file1.txt
- 足以超过最大 shell 行长度(通常为 128KB 或更多)。
最后,它通过管道将xargs
into的输出从该行中sed
剥离出来。,
如果您希望在 中的每个 ID 之后添加换行符select.sql
,请将脚本的最后一行更改为:
sed -i "s/FLAG/${S_ids}/g; s/, /\n/g" "$sqlfile"
输出将是:
SELECT *
FROM CUSTOMERS
WHERE ID IN ('1234',
'1345',
'8427',
'2132',
'3243');
答案3
$ FLAG=$(awk -F\| '{printf("%s, ", $1)}' file1.txt)
$ echo $FLAG
1234, 1345, 8427, 2132, 3243,
$ sed "s/FLAG/${FLAG%%, }/" select.sql
SELECT *
FROM CUSTOMERS
WHERE ID IN (1234, 1345, 8427, 2132, 3243);
这取决于标志列表是否足够小以适合命令行。如果不是,您可以使用获取线在 awk 中处理 file1.txt,以BEGIN
模式收集替换字符串,然后处理 select.sql。