1

UUID を必要とする SQL ステートメントを作成するために使用したい複数行のテキスト ファイルがあります。sed またはその他のシェル コマンド ユーティリティを使用して SQL を生成する方法を考え出そうとしています。

Example input:
A
B
C

Example Output:
insert into table values ('7CC92727-D743-45E0-BE57-9FEB2B73BD18','A');
insert into table values ('94E03071-F457-48DD-86E2-AF26309A192D','B');
insert into table values ('1F17525C-9215-4FC4-A608-4FA43C0B2B14','C');

uuidgen コマンドを使用して新しい UUID を生成できますが、これまでのところ、そのコマンドを sed で使用する方法は見つかりませんでした。

更新: 回答のおかげで、cygwin で機能する sed コマンドを思いつくことができました。

教訓的な目的で SQL 値を引用せずに表現します。

sed 's/.*/echo "insert into table values (`uuidgen | tr -d \r`,&)"/e' file.txt

引用符付き:

sed 's/.*/echo "insert into table values '\''(`uuidgen | tr -d \r`'\'','\''&'\'')"/e' file.txt
4

3 に答える 3

3

While ループを使用した非常に読みやすい Bash ソリューション

デフォルトのREPLY変数を使用して、ファイルを Bash ループに読み込むことができます。例えば:

while read; do
    echo "insert into table values ('$(uuidgen)','$REPLY');"
done < /tmp/foo

読みにくい Sed ソリューション

sed -e 's/.*/echo "insert into table values (\\"$(uuidgen)\\",\\"&\\");"/e' \
    -e "s/\"/'/g" /tmp/foo

while ループは、置換文字列で引用符をエスケープする必要があるため、sed の代替よりもはるかに読みやすくなっています。sed ソリューションは、特定のメタ文字が存在する場合にエラーを引き起こす可能性がある sed 式内でファイルの内容を評価しているため、かなり脆弱です。最後に、この特定の sed ソリューションは/eフラグに依存しています。これは、お使いのプラットフォームでは利用できないGNU sed 拡張機能です。

GNU sed マニュアルでは、フラグについて次のように説明しています。

このコマンドを使用すると、シェル コマンドからの入力をパターン スペースにパイプできます。置換が行われた場合、パターン空間で見つかったコマンドが実行され、パターン空間がその出力に置き換えられます。末尾の改行は抑制されます。実行するコマンドにヌル文字が含まれている場合、結果は未定義です。これは GNU sed 拡張です。

テスト

両方のスクリプトは、次のフィクスチャ データを含む/tmp/fooに対してテストされました。

A
B
C

Bash サンプル出力:

insert into table values ('fe0ca930-456b-4265-810c-219eb93c4c73','A');
insert into table values ('34b088eb-3dc0-46fa-85ca-efaf3f0c0f4b','B');
insert into table values ('5d271207-99fe-4ca2-8420-3b8ca774e99b','C');

GNU sed 出力例:

insert into table values ('4c924b78-dc70-441d-928e-638fec9f3ea1','A');
insert into table values ('29f424d4-6e33-4646-a773-cd0e96ebb874','B');
insert into table values ('39534c05-6853-4390-a6b6-4a19fad296b1','C');

結論

Bash ソリューションは、sed ソリューションよりも明確で堅牢に見えます。ただし、どちらのソリューションも元の質問で提供されたフィクスチャ データで明らかに機能するため、実際のデータで最適な方を選択する必要があります。

于 2012-06-23T09:16:50.573 に答える
2
sed 's/.*/echo "`uuidgen`,&"/e' input |
    sed -r 's/(.*),(.*)/insert into table values("\1","\2");/' |
        tr '"' "'"

insert into table values('c609f5ab-28ce-4853-bd67-7b6b4ca13ee3','A');
insert into table values('01ae6480-1b52-49a8-99a3-f2bba7ec3064','B');
insert into table values('a41122e8-5e4f-4acc-b62a-bc4ad629677e','C');
于 2012-06-23T06:54:22.507 に答える
1

これはあなたのために働くかもしれません:

echo -e 'a\nb\nc' | 
sed 's/.*/uuidgen;echo "&"/' | 
sh | 
sed 'N;s/^\(.*\)\n\(.*\)/insert into table values('\''\1'\'',\2);/'
insert into table values('c9939dfe-5a74-465a-b538-66aeba774b6b',a);
insert into table values('da6684f2-3426-4561-b41d-7b507d2d79ee',b);
insert into table values('23c72ef5-2a50-4a09-b964-83eea3c54e83',c);

またはGNU sedを使用:

echo -e 'a\nb\nc' | 
sed 'h;s/.*/uuidgen/e;G;s/^\(.*\)\n\(.*\)/insert into table values('\''\1'\'',\2);/'
insert into table values('ac1a130c-50a3-43ce-8d41-987ca0d942b7',a);
insert into table values('59426b2f-cf03-4233-bcc2-3ce05c47bece',b);
insert into table values('fdec75d6-313e-48c4-adfb-335721a0f6e7',c);
于 2012-06-23T07:45:58.830 に答える