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.