【问题标题】:Add new uuid to each line of a file using sed or equivalent command使用 sed 或等效命令将新的 uuid 添加到文件的每一行
【发布时间】:2012-06-25 10:04:18
【问题描述】:

我有一个多行文本文件,我想用它来创建需要 UUID 的 SQL 语句。我正在尝试想出一种使用 sed 或其他一些 shell 命令实用程序生成 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

【问题讨论】:

    标签: shell sed uuid


    【解决方案1】:
    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');
    

    【讨论】:

      【解决方案2】:

      这可能对你有用:

      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);
      

      【讨论】:

        【解决方案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 extension,可能在您的平台上不可用。

        GNU sed 手册对标志的描述如下:

        此命令允许将来自 shell 命令的输入通过管道传输到模式空间。如果进行了替换,则执行在模式空间中找到的命令,并将模式空间替换为其输出。尾随换行被抑制;如果要执行的命令包含空字符,则结果未定义。这是一个 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 解决方案更清晰、更强大。但是,这两种解决方案显然都适用于原始问题中提供的夹具数据,因此您应该选择最适合您的实际数据的解决方案。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          • 2019-10-19
          • 1970-01-01
          • 2020-07-01
          • 2012-04-02
          • 2015-04-12
          相关资源
          最近更新 更多