私は次のテキスト行を作成しました。
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の場合は呼び出されますが、-r
BSDの場合は呼び出されます-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進数またはコロン)が一致します。