ファイルの値を変更する

ファイルの値を変更する

ファイルがあります:

$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」で読んでください。

xargsxargs 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を処理します。

関連情報