在Linux和OSX上用唯一的guid替换每个匹配值的文本

时间:2016-12-02 02:19:44

标签: linux bash macos sed

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

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

所有这些id都是唯一的。

我想编写一个命令,为所有id s

生成新的唯一值

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

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

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

2 个答案:

答案 0 :(得分:2)

For in-placing editing with sed's -i option, there is no cross-platform syntax that works without creating a backup file, as explained in this answer of mine (you must use either -i '' (BSD/macOS) or just -i (GNU), but with creation of a backup file something like -i.bak does work with both implementations).

That said, awk is the better tool for this task anyway, because Awk scripts allow invoking shell commands and external utilities on demand:

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

This assumes that filenames have no embedded newlines, which is rarely a real-world concern.

  • The command uses only POSIX-compliant shell features, utilities and options, with the exception of:

    • the uuidgen utility, which, however, is available on both Linux and macOS, as well as FreeBSD and its variants.
  • Sadly, Mawk (which is Ubuntu's default Awk) doesn't support duplication expressions such as {36}, which is why the less specific + is used above; if you know that you'll be using only either BSD or GNU Awk, however, you can still use {36}.

  • The command supports replacing multiple UUIDs in each input file.

On a side note: GNU Awk v4.1+ allows in-place updating with -i inplace, similar to Sed's -i option, which would allow for a single-command find solution with -exec, but neither BSD Awk nor Mawk support it.

答案 1 :(得分:-1)

所以我想通了(作弊)。

每个文件只有一个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

对于一般情况,问题仍然存在,如果可以一次性完成。