是否可以在变量中获取 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 终止后变量将失去其值。
我在脚本中遇到问题,我想知道是否可以存储 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 终止后变量将失去其值。