是否可以在变量中获取 grep 路径输出?

Is it possible to get the grep path output in a variable?

我在脚本中遇到问题,我想知道是否可以存储 grep 匹配结果的路径?

我在 RHEL 7 上,该脚本是对 rsyslog.conf 文件的检查,该文件完成或向参数添加了正确的值(CIS rhel7 基准测试,第 4.2.1.3 部分)。

到目前为止的完整脚本:

#!/bin/bash

if grep "^$FileCreateMode" /etc/rsyslog.conf /etc/rsyslog.d/*.conf
then
    read -p "Is $FileCreateMode superior or equal to 0640 ? [y/n]" rep
    if [ $rep == "y" ]
    then
        echo "No action needed"
    else
        read -p "Enter the new $FileCreateMode value (0640 recommanded)" rep2
        sed -i "/^$FileCreateMode/ $rep2" 
        echo "$FileCreateMode new value is now $rep2"
    fi
else
    echo "$FileCreateMode doesn't exist in rsyslog conf files"
    read -p "What's the path of the file to modify ?(Press [ENTER] for default /etc/rsyslog.conf)" path
    if [ $path -z ] 
    then
        echo "$FileCreateMode 0640" >> /etc/rsyslog.conf
    else
        echo "$FileCreateMode 0640" >> $path
    fi
fi

所以我的问题出在第 11 行的 sed 上。 如果我在第 3 行的 grep 匹配到一个变量以在第 11 行重用它,我是否能够获得正确的路径。

而且我正在努力使用同一个 sed,因为我希望他替换 $FileCreateMode 之后的值,但它不断更改 $FileCreateMode 字符串。

我也尝试过这种语法,但我仍然没有得到我想要的结果

sed -i -e "s,^\($FileCreateMode[ ]*\).*, 0640 ,g" /etc/rsyslog.conf

在此先感谢您提供的任何帮助,祝您有愉快的一天:)

编辑:

应要求,我在这里进行了简化。

我想在 /etc/rsyslog.conf 和 /etc/rsyslog.d/*.conf 中 grep $FileCreateMode 并且我正在尝试获取目标文件(可能是 rsyslog.conf 但是它可以是 rsyslog.d 中的 testpotato.conf) 到变量(如 $var)中,以便能够在第 11 行使用我的 sed 中的路径,如

sed -i "/^$FileCreateMode/ 0640" $var

对于我执行此命令时的 sed 问题,我想要

old : $FileCreateMode 0777
sed -i "/^$FileCreateMode/ 0640" $var
new : $FileCreateMode 0640

但是我得到了

old : $FileCreateMode 0777
sed -i "/^$FileCreateMode/ 0640" $var
new : 0640 ($FileCreateMode is deleted)

希望我更稳定,再次感谢,随时询问更多细节

使用$()将grep的结果赋值到一个变量中,然后使用for循环逐一处理文件:

# Assign grep results to FILES
FILES=$(grep -l '^$FileCreateMode' /etc/rsyslog.conf /etc/rsyslog.d/*.conf)

# Check if FILES variable is not empty
if [[ -n ${FILES} ]]; then
    # Loop through all the files
    for file in ${FILES}; do
        # ...
        sed -iE "s/^(\$FileCreateMode\s+)[[:digit:]]+/${rep2}/" ${file}
        # ...
    done
else
    # OP's logic for when $FileCreateMode doesn't exist in any of the files

sed 修复:

请注意,我还更新了您的 sed 表达式(上文)。您非常接近,但是您必须双重转义美元符号:一次是在“”中使用它,一次是为了在正则表达式中不将其解释为 END_OF_LINE。

如果您的 grep 支持 -H,您可以这样做:

while grep -H "^$FileCreateMode" /etc/rsyslog.conf /etc/rsyslog.d/*.conf \
        | IFS=: read path line; do

        # Here, $path is the path to the file that matches
        # and $line is the line that matched.
done

如果您愿意,可以使用 if ...; then 而不是 while ...; do 请注意,子 shell 终止后变量将失去其值。