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

时间:2018-06-11 15:18:58

标签: bash sed grep rhel

我在脚本中遇到问题,我想知道是否可以存储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[ ]*\).*,\1 0640 ,g" /etc/rsyslog.conf

提前感谢您提供的任何帮助,祝您度过愉快的一天:)

编辑:

根据要求我简化了这里。

我想在/etc/rsyslog.conf和/etc/rsyslog.d/*.conf中grep $ FileCreateMode并且我试图获取目标文件(可能是rsyslog.conf但它可以是testpotato .ys在rsyslog.d中)变成一个变量(比如$ 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)

希望我更明白,再次感谢并随时提出更多细节

2 个答案:

答案 0 :(得分:1)

使用$()将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修正:

请注意,我还更新了您的sed表达式(上图)。你非常接近,但你必须双重逃避美元符号:一次在""中使用它,并且一次使它在正则表达式中不被解释为END_OF_LINE。

答案 1 :(得分:0)

如果您的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终止后,变量将丢失其值。