替换文件中的值

替换文件中的值

我有一个文件:

$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 或更多)。

最后,它通过管道将xargsinto的输出从该行中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。

相关内容