私はファイルを持っています:
$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」の値をWordFLAGのファイル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
を試しましたが、期待した結果が得られませんでした。
これが機能しない理由は、エラーメッセージ(提供するために省略した)から推測できます。
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 ','
_#! /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-」と読みます再び"。
xargs
を実行するコマンドがない場合、デフォルトは_xargs echo
_になり、すべての出力行(file1.txtの単一引用符で囲まれた最初のフィールド)がスペースで区切られた1行に配置されます。これは、_file1.txt
_に数万の行がない限り機能します-シェルの最大行長(通常は128KB以上)を超えるのに十分です。
最後に、xargs
の出力をsed
にパイプして、最後の_,
_を行から削除します。
_select.sql
_の各IDの後に改行を含める場合は、スクリプトの最後の行を次のように変更します。
_sed -i "s/FLAG/${S_ids}/g; s/, /\n/g" "$sqlfile"
_
出力は次のようになります。
_SELECT *
FROM CUSTOMERS
WHERE ID IN ('1234',
'1345',
'8427',
'2132',
'3243');
_
$ 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でgetlineを使用してfile1.txtを処理し、置換文字列をBEGIN
パターンで収集してから、select.sqlを処理できます。