sed 替换文件列表中的子字符串

sed 替换文件列表中的子字符串

我有很多让加密续订 cron 文件的列表。每个文件都有一个 cron 时间表,我正在尝试将小时和分钟替换为半夜晚些时候的时间。我正在尝试使用 bash 脚本来执行此操作,并使用 sed 来更新小时和分钟。为了我的命,我无法找到该死的 sed 来替换。我尝试浏览许多论坛,但无法完全获得正确的设置。这是我得到的:

for FILE in $(find ./renew -type f -name "letsen*") 
do
        # This will be the new min / hour
        TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
        sed -e 's/[0-9]+\W[0-9]+})/$TIMESET/' $FILE;
done

以下是 LetsEncrypt 文件的示例:

33 19 * * 5 root /bin/bash /home/forge/.letsencrypt-renew/711959 > /home/forge/.letsencrypt-renew/711959.out$

我缺少什么?感谢任何帮助!

更新

感谢埃德加·马加隆,这是对我有用的解决方案:

for FILE in ./renew/letsen*
  do
        [[ -f $FILE && ! -L $FILE ]] && {
          TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
          
          # I think it's best to do a backup like what was suggested.
          sed -i'.bak' -Ee "s/[0-9]+[0-9]+/$TIMESET/" "$FILE";
        }
done

echo "Done! Have a great day~!";

答案1

您不应该使用find迭代文件列表。看为什么循环查找的输出是不好的做法?

您可以使用一个简单的for循环来迭代 name 的文件列表letsen*。您可以-type f使用 进行复制[[ -f $FILE ]]

关于该sed命令,我看到您正在使用单引号',但当您想用 then 替换小时和分钟时$TIMESET,您应该使用双引号"。另请参阅此:bash中单引号和双引号的区别。您应该使用-E选项sed才能使用扩展正则表达式

我不确定你为什么})/[0-9]+\W[0-9]+})/.我认为这是没有必要的。因为如果我没记错的话你想用33 19存储在$TIMESET.
假设您想像我之前所说的那样替换这些值,那么您的代码应如下所示:

for FILE in ./renew/letsen*
do
        [[ -f $FILE ]] && {
        # This will be the new min / hour
        TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
        sed -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"
        
        #Or I guess you can remove '\W' and use a single space.
        #I'm not sure if cron files have always a space between those numbers.
        #If so, then you could use this:
        sed -Ee "s/[0-9]+ [0-9]+/$TIMESET/" "$FILE"
      
        }
done

如果你想编辑每个文件到位您应该-i向命令添加选项sed

#If you want to backup every file:
sed -i'.bak' -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"
#Without  backup
sed -i -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"

相关内容