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

Bash 是否可以在变量中获取grep路径输出?,bash,sed,grep,rhel,Bash,Sed,Grep,Rhel,我在脚本中遇到问题,我想知道是否可以存储grep匹配结果的路径 我在RHEL 7上,脚本是对rsyslog.conf文件的检查,该文件完成或向参数添加正确的值(CIS RHEL 7基准,第4.2.1.3部分) 到目前为止的完整脚本: #!/bin/bash if grep "^\$FileCreateMode" /etc/rsyslog.conf /etc/rsyslog.d/*.conf then read -p "Is $FileCreateMode superior or equ

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

我在RHEL 7上,脚本是对rsyslog.conf文件的检查,该文件完成或向参数添加正确的值(CIS RHEL 7基准,第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上。 如果我的第三行grep匹配到一个变量,在第11行重用它,我是否能够得到正确的路径

我正在努力使用相同的sed,因为我希望他替换$FileCreateMode之后的值,但它一直在更改$FileCreateMode字符串

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

sed -i -e "s,^\($FileCreateMode[ ]*\).*,\1 0640 ,g" /etc/rsyslog.conf
提前感谢您带来的任何帮助,祝您度过愉快的一天:)

编辑:

按照要求,我在这里简化

我想将/etc/rsyslog.conf和/etc/rsyslog.d/*.conf中的$FileCreateMode grep到一个变量中(比如$var),以便能够使用sed中第11行的路径,比如

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:]]+/\1${rep2}/" ${file}
        # ...
    done
else
    # OP's logic for when $FileCreateMode doesn't exist in any of the files
sed
fix:


请注意,我还更新了您的
sed
表达式(如上)。您非常接近,但您必须双倍避开美元符号:一次是为了在“”中使用它,另一次是为了使它不会被解释为正则表达式中行的结尾。

如果您的
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。。。;然后
而不是
而。。。;请注意,子shell终止后,变量将丢失其值。

这不是一个错误。您是否可以发布这样一个示例,或者更详细地解释
grep
在不同情况下返回的内容?事实上,我不完全理解这个问题。我明白你在做什么,你要确保$FileCreateMode至少是0640。但是在那之后你想要完成什么呢?sed看起来还不错。如果我运行您的grep,我会得到
/etc/rsyslog.conf:$filecreatemode0640
,那么您希望重用的正确路径是什么?用问题的例子更好地解释你的问题。我编辑这篇文章是为了更具体,我希望它能更容易理解。抱歉,如果第一篇文章有点粗略,这是我第一次在这里发布。你不是在找什么吗?@rkta我用错了,然后我尝试替换$FileCreateMode之后的内容,我会尝试不同的打字,感谢如果您在命令行上枚举所有输入文件,则不需要使用
-R
选项。好样的@tripleee!我已将
grep-Rl
更新为
grep-l
@ilkkachu谢谢,删除了我的评论,我是盲人,对不起@ilkkachu,我同意你关于“文件名中的空格或全局字符”的说法。然而,由于OP在
/etc/rsyslog.conf
/etc/rsyslog.d/*.conf
中显示,因此出现这些字符的可能性非常小。因此,处理它们只会给脚本带来不必要的复杂性。@UmkaDK非常感谢,这正是我想要的!随着循环,它的工作,因为我想它了。对于sed,我设法使用以下语法:sed-i-e“/^\$FileCreateMode/s/*/$rep2/”但我会检查您的语法,因为它看起来更完整。再次感谢!使用
而grep。。。;做done
在OP的问题中省略了逻辑ELSE条件,将“$FileCreateMode不存在于rsyslog conf文件中”代码放在循环中会导致不必要的低效。