我在脚本中遇到问题,我想知道是否可以存储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)
希望我更明白,再次感谢并随时提出更多细节
答案 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终止后,变量将丢失其值。