替换多个文件中的 1 行

替换多个文件中的 1 行

我在一个目录中有一些文本文件。它们都有许多不同的字符串,但 1 个字符串对于所有字符串都是相同的。

Acct-Session-Id = "XXXXXXXX-XXXXXXXX"

其中 X - 十六进制格式的符号。

我需要用随机 XXXXXXXX-XXXXXXXX 数字替换所有这些文件中的此 ID。所有文件中的编号必须相同。替换后,文件必须以相同的名称保存。

我尝试用 sed 执行此操作,但没有成功......

答案1

像这样,使用

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

相关内容