ファイルがあります:
$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
FLAGという単語のファイル入力に変数 "S_ids"の値を入れる必要があります。select.sql
結果は次のようになります。
$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
コマンドは複数行の値を受け入れません。複数の行を1つに縮小する必要があります。次のスクリプトを使用してこれを実行できます。
#!/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の一重引用符で囲まれた最初のフィールド)が空白で区切られた1行に配置されるように実行するコマンドはありません。これはfile1.txt
、最大シェルライン長(通常128 KB以上)を超えるのに十分な数万行がない限り機能します。
最後に、xargs
出力をパイプで接続してラインから取り除きます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を処理します。