我在一个目录中有一些文本文件。它们都有许多不同的字符串,但 1 个字符串对于所有字符串都是相同的。
Acct-Session-Id = "XXXXXXXX-XXXXXXXX"
其中 X - 十六进制格式的符号。
我需要用随机 XXXXXXXX-XXXXXXXX 数字替换所有这些文件中的此 ID。所有文件中的编号必须相同。替换后,文件必须以相同的名称保存。
我尝试用 sed 执行此操作,但没有成功......
答案1
像这样,使用awk:
id=$(openssl rand -hex 8 | sed 's/./-&/9')
awk -v id=$id '$1 == "Acct-Session-Id"{$3="\042"id"\042"}1' file
输出
Acct-Session-Id = "f7ea78e0-1eeb7b09"
然后:
id=$(openssl rand -hex 8 | sed 's/./-&/9')
while IFS= read -r f; do
awk -v id=$id '$1 == "Acct-Session-Id"{$3="\042"id"\042"}1' "$f" > /tmp/tmp$$
mv /tmp/tmp$$ "$f"
done < <(grep -l 'Acct-Session-Id' .)
另一种解决方案,使用珀尔(不需要循环和临时文件):
export id=$(openssl rand -hex 8 | sed 's/./-&/9')
perl -i -lane '
$F[2] = "\042$ENV{id}\042" if $F[0] eq "Acct-Session-Id";
print join " ", @F
' files*
答案2
由于您用 标记了您的问题Linux
,并且假设您指的是 GNU/Linux,您可以编写如下脚本:
#! /bin/sh -
IFS= read -r uuid < /proc/sys/kernel/random/uuid || exit
id=${uuid%-*-*}
id=${id%-*}${id##*-}
grep -rl --null -e 'Acct-Session-Id = ".*"' -- "$@" |
xargs -r0 sed -i -e 's/\(Acct-Session-Id = \)"[^"]*"/\1"'"$id"'"/g' --
被调用为:
path/to/that-script path/to/dir-or-file path/to/other/dir-or-file...
答案3
sed 单行
id=$(hexdump -vn8 -e '4/1 "%02x" "-"' /dev/urandom);
sed -ri 's,^Acct-Session-Id = "[[:xdigit:]]{8}-[[:xdigit:]]{8}"$,Acct-Session-Id = "'"${id%?}"'",' ./*.txt;
cat /dev/urandom
将输出随机字节
hexdump
将打印文件的十六进制视图
-v
= 不抑制空字节
-n <length>
= 仅前 n 个字节(与 head -c 相同)
-e 4/1
将每行输出 4 个字节 x 1,格式为%02x
(2 位数字),行之间用-
so 的值分隔id
应该是这样的cf41f825-8b1e4c1c-
(不幸的是尾随-
)
sed -i
./*.txt 将编辑所有文件
's,^find$,'replace','
并将搜索单词'寻找'^
在行的开头,并且行
必须在单词之后立即终止$
(完全匹配整行),
'replace'
为了解析变量,行之间必须不加引号
("$id"
不会在单引号内求值)
如果你想匹配所有字符串,^
你可以删除$
[[:xdigit:]]
将匹配十六进制数字之间的一个字节0-f
(thx @GillesQuenot)
{8}
前一个字节必须连续存在 8 次
${id%?}
将$id
使用字符串操作输出,如果出现在任何单个字节的
%
结尾通配符中,则删除最短的出现 ,因此替换 id 类似于
?
cf41f825-8b1e4c1c
在此示例中,只有 1. + 3. 行符合您的请求并将被更改,其他行保持不变
sed
仅当 line 是精确行、XXX
是有效的十六进制字符串并嵌入双引号时才替换"..."
,如果存在其他空格或任何其他字符,则该行保持不变。该词Acct-Session-Id
区分大小写。文件名作为最后一个参数传递./*.txt
,行被替换-i