sedを使用してSQLクエリとして使用するには、テキストファイルに一重引用符を挿入する必要があります。

sedを使用してSQLクエリとして使用するには、テキストファイルに一重引用符を挿入する必要があります。

私は次のテキスト行を作成しました。

INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,,00:23:32:c2:a9:e8,Auth-Type,:=,Accept);

sedを使って次のようにしたいと思います。

INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');

これは文脈でより意味があり、過去17時間(明らかに)これについてもっと学びました。

#!/bin/bash
ssh [email protected] brmacs >>MACS.txt mv MACS.txt /etc/persistent scp [email protected]:/etc/persistent/MACS.txt MACS.txt
sed -i "1d" MACS.txt
head -c 58 MACS.txt >>shortmacs.txt
tail -c 18 shortmacs.txt >>usermac.txt
sed 's/"//g' usermac.txt >>usermacrdy.txt
sed -i 's/^/INSERT INTO `radcheck`(`id`, `username`, `attribute`, `op`, `value`) VALUES (,'',/' usermacrdy.txt
sed "s/$/','Auth-Type',':=','Accept');/" usermacrdy.txt > sqlquery.txt
sed -i "s/,,/\,\'\',\'/" sqlquery.txt
rm -f MACS.txt
rm -f shortmacs.txt
rm -f usermac.txt
rm -f usermacrdy.txt

働く! ! !

ヘッダーとトレーラーはUBNT CPEデバイスから送信された生のテキストファイルからMACアドレスを切り取り、sedを介してMACアドレスの周りにSQL構文を構築します。

id結局、クエリの一部が成功するために必要ではないことがわかったので、今や少し同じ状況にあります。

sed -i 's/^/INSERT INTO `radcheck`(`username`, `attribute`, `op`, `value`) VALUES (/' usermacrdy.txt
sed "s/$/','Auth-Type',':=','Accept');/" usermacrdy.txt > sqlquery.txt
sed -i "s/\,\'\',\'//" sqlquery.txt

ベストアンサー1

必要な一重引用符を含める方法は4つあります。

一重引用符文字列内で一重引用符文字列をエスケープすることはできません。ただし、引用符で囲まれた文字列を終了し、エスケープされた単一引用符を挿入して、新しい単一引用符で囲まれた文字列を開始できます。したがって、中間に一重引用符を入れるには、次のように'ab'します'a'\''b'。または、必要なsedコマンドを使用してください。

$ sed -r 's/,([^ ),]+)/,'\''\1'\''/g; s/,,/,'\'\'',/g' file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');

2番目の方法は、二重引用符で囲まれた文字列を使用することです。この場合、単一引用符を簡単に挿入できます。

$ sed -r "s/,([^ ),]+)/,'\1'/g; s/,,/,'',/g" file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');

二重引用符で囲まれた文字列の問題は、シェルがこれを処理する方法です。しかし、ここにはシェルアクティブ文字がないので簡単です。

3番目の方法は、PM2Ringに示されているように16進エスケープを使用することです。

コメントでJonathan Lefflerが提案した4番目のアプローチは、sedコマンドを別々のファイルに保存することです。

$ cat script.sed 
s/,([^ ),]+)/,'\1'/g
s/,,/,'',/g
$ sed -rf script.sed file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');

この方法の利点は、sedシェルの干渉なしにコマンドを直接読み取ることができることです。これにより、シェルアクティブ文字をエスケープする必要がなくなり、コマンドを純粋な構文で入力できるようになりますsed

ソリューションsedの仕組み

ヒントは、目的のカンマ区切り文字列の周りに一重引用符を付け、他の文字列の周りには入れないことです。提供された単一の例に基づいて、1つのアプローチは次のとおりです。

  • s/,([^ ),]+)/,'\1'/g

    カンマの後にスペースがなく、カンマがなく、右角かっこではない文字が1つ以上検索されます。これらの文字は一重引用符で囲まれています。

  • s/,,/,'',/g

    連続したカンマを見つけ、その間に2つの単一引用符を配置します。

OSXおよびその他のBSDプラットフォーム

さらにバックスラッシュを避けるために、上記の式ではsed拡張正規表現を使用します。 GNUの場合は呼び出されますが、-rBSDの場合は呼び出されます-E。さらに、一部の非GNUはsedセミコロンで区切られた複数のコマンドを許可しません。したがって、OSXでは、次のことを試してみてください。

sed -E -e "s/,([^ ),]+)/,'\1'/g" -e "s/,,/,'',/g" file

付録:MACアドレスの一致

コメントから次の情報を入手できます。

$ cat file3
 INSERT INTO radcheck(username, attribute, op, value) VALUES (00:23:32:c2:a9:e8,'Auth-Type',':=','Accept'); 

また、開いている括弧の後のMACアドレスの周りに一重引用符を入れようとします。これを行うことができる必要があります。

$ sed -r "s/\(([[:xdigit:]:]+)/('\1'/" file3
 INSERT INTO radcheck(username, attribute, op, value) VALUES ('00:23:32:c2:a9:e8','Auth-Type',':=','Accept'); 

すべてのロケールの[:xdigit:]すべての16進数と一致します。したがって、([[:xdigit:]:]+)MACアドレス(16進数またはコロン)が一致します。

おすすめ記事