首页 > 解决方案 > Bash:从文件中读取正则表达式并将它们替换为 sed inline 作为变量

问题描述

我对 sed 如何与变量交互感到困惑。我正在从文件中读取正则表达式列表,然后将其替换为 SED 以掩盖日志文件中的某些敏感信息。如果我对正则表达式进行硬编码,SED 可以完美地工作,但是在与变量一起使用时它的行为会有所不同。

con-list.txt contain below:
(HTTP\/)(.{2})(.*?)(.{2})(group\.com)
(end\sretrieve\sfacility\s)(.{2})(.*?)(.{3})$

不确定正则表达式的美元符号是否干扰了 SED 命令。

input="/c/Users/con-list.txt"
inputfiles="/c/Users/test.log"
echo $inputfiles
while IFS= read -r var
do
  #echo "Searching $var"
  count1=`zgrep -E "$var" "$inputfiles" | wc -l`
  if [ ${count1} -ne 0 ] 
  then
    echo "total:${count1} ::: ${var}"
    sed -r -i "s|'[$]var'|'\1\2XXXX\4\5'|g" $inputfiles #this doesnt work
    sed -r -i "s/(HTTP\/)(.{2})(.*?)(.{2})(group\.com)/'\1\2XXXX\4\5'/g"     $inputfiles #This works
    egrep -in "${var}" $inputfiles
  fi
done < "$input"

我需要 SED 接受正则表达式作为从文件中读取的变量。所以我可以自动屏蔽日志中的敏感信息。

$ ./zgrep2.sh
/c/Users/test.log
total:4 ::: (HTTP\/)(.{2})(.*?)(.{2})(group\.comp\.com\@GROUP\.COM)
sed: -e expression #1, char 30: invalid reference \5 on `s' command's RHS

标签: bashvariablesseddata-masking

解决方案


您的想法是正确的,但是您忘记将sed命令中的正则表达式放在双引号下$var以进行扩展。

此外,您不需要使用wc -l来计算出现的匹配。所有实用程序系列grep都实现了一个-c返回匹配计数的标志。也就是说,您甚至不需要计算匹配项,而是简单地使用命令的返回码(如果找到匹配项)

if zgrep -qE "$var" "$inputfiles" ; then

假设您可能需要将计数用于调试目的,您可以继续使用您的方法修改您的脚本,如下所示

请注意如何var在替换中插入sed,使其在双引号下展开,一旦展开,则使用单引号保留文字值。

while IFS= read -r var
do
  count1=$(zgrep -Ec "$var" "$inputfiles")
  if [ "${count1}" -ne 0 ] 
  then
    sed -r -i 's|'"$var"'|\1\2XXXX\4\5|g' "$inputfiles"
    sed -r -i "s/(HTTP\/)(.{2})(.*?)(.{2})(group\.com)/'\1\2XXXX\4\5'/g" "$inputfiles"
    egrep -in "${var}" "$inputfiles"
  fi
done < "$input"

推荐阅读