我有一个包含大量文件的文件夹。在其中一些文件中有一行像这样
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
。
显然,首选简洁易读的东西。
答案 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:
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
对于一般情况,问题仍然存在,如果可以一次性完成。