在 Linux 和 OSX 上用唯一的 uuid 替换每个匹配的字符串值

Posted

技术标签:

【中文标题】在 Linux 和 OSX 上用唯一的 uuid 替换每个匹配的字符串值【英文标题】:Replace each matched string value with unique uuid on Linux and OSX 【发布时间】:2017-04-16 20:42:29 【问题描述】:

我有一个包含一堆文件的文件夹。在其中一些文件中有这样一行

id = "8c09e1ce-56b6-4aa5-8307-8998f507b594"

所有ids 都是独一无二的。

我想编写一个命令,为所有ids 生成新的唯一值

我有一个 sed 命令将匹配原始行 's/id = \"[a-zA-Z0-9-]\36\\"//g' 但我不知道如何动态地使替换工作。

有一些类似的 *** 问题 (like this one),但我无法让解决方案在 OSX 和 Linux 上可靠地工作,这是我的要求之一。不过他们都安装了uuidgen

简洁易读的东西显然是首选。

【问题讨论】:

您提到的 ID 字符串的预期输出是什么。 嘿@Inian 我想用所有这些文件中的新 guid 替换 guid 值 【参考方案1】:

对于使用sed-i 选项进行就地编辑,没有跨平台语法可以创建备份文件,正如我的this answer 中所述(你必须使用 either -i '' (BSD/macOS) 只是 -i (GNU),但是 with 创建一个备份文件就像-i.bak 确实适用于这两种实现)。

也就是说,无论如何,awk 是完成这项任务的更好工具,因为 Awk 脚本允许按需调用 shell 命令和外部实用程序:

find . -type f -name '*.extension' | while IFS= read -r fpath; do
  awk '
    BEGIN  FS=OFS=" = "  
    $2 ~ /^\"[a-zA-Z0-9-]+\"$/  "uuidgen" | getline uuid; $2 = "\"" uuid "\"" 
    1
  ' "$fpath" > "$fpath.tmp" && mv "$fpath.tmp" "$fpath"
done

这假定文件名没有嵌入换行符,这在现实世界中很少引起关注。

该命令仅使用符合 POSIX 标准的 shell 功能、实用程序和选项,但以下情况除外:

uuidgen 实用程序,不过,它可在 Linux 和 macOS 以及 FreeBSD 及其变体上使用。

遗憾的是,Mawk(这是 Ubuntu 的默认 Awk)不支持重复表达式,例如 36,这就是为什么上面使用不太具体的 + 的原因;但是,如果您知道您将只使用 BSD 或 GNU Awk,您仍然可以使用 36

该命令支持在每个输入文件中替换多个 UUID。

附带说明:GNU Awk v4.1+ 允许使用 -i inplace 就地更新,类似于 Sed 的 -i 选项,这将允许单个命令 find -exec 的解决方案,但 BSD Awk 和 Mawk 都不支持。

【讨论】:

【参考方案2】:

所以我想通了(通过作弊)。

每个文件只有一个id,所以我决定遍历文件并分别为每个文件运行sed,如下所示:

for i in `find . -name "*.extension" -type f`; do
    uuid=$(uuidgen)
    sed -i '' -e "s/id = \"[a-zA-Z0-9-]\36\\"/id = \"$uuid\"/g" $i
done

这个问题仍然适用于一般情况,如果可以一次性完成的话。

【讨论】:

请do not use for to parse command output。此外,您的sed -i '' 仅适用于 BSD Sed,不适用于 GNU Sed。请双引号 $i 以确保其值按原样使用。不需要 Sed 脚本的 s 函数调用中的 g 选项,因为每个输入行最多有 1 个 UUID。

以上是关于在 Linux 和 OSX 上用唯一的 uuid 替换每个匹配的字符串值的主要内容,如果未能解决你的问题,请参考以下文章

linux C语言如何生成uuid(通用唯一识别码Universally Unique Identifier)?

linux C语言如何生成uuid(通用唯一识别码Universally Unique Identifier)?

linux 中文件有uuid吗

如何在 linux/Mac OSX 中获取网络适配器统计信息?

linux网卡的uuid有啥用

如何在Linux 中获取硬盘分区或文件系统的UUID?