Bash 脚本“sed:第一个 RE 可能不为空”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9343692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:35:34  来源:igfitidea点击:

Bash script 'sed: first RE may not be empty' error

bashsed

提问by user1152142

I have written the following bash script, it is not finished yet so it is still a little messy. The script looks for directories at the same level as the script, it then searches for a particular file within the directory which it makes some changes to.

我写了下面的 bash 脚本,它还没有完成,所以它仍然有点乱。该脚本查找与脚本处于同一级别的目录,然后在目录中搜索特定文件,并对其进行一些更改。

When I run the script it returns the following error:

当我运行脚本时,它返回以下错误:

sed: first RE may not be empty
sed: first RE may not be empty
sed: first RE may not be empty
sed: first RE may not be empty
sed: first RE may not be empty
sed: first RE may not be empty
sed: first RE may not be empty

My research tells me that it may be something to do with the '/'s in the directory name strings but I have not been able to solve the issue.

我的研究告诉我,这可能与目录名称字符串中的“/”有关,但我无法解决该问题。

Despite the error messages the script seems to be working fine and is making the changes to the files correctly. Can anyone help explain why I am getting the error message above?

尽管有错误消息,脚本似乎工作正常并且正确地对文件进行了更改。任何人都可以帮助解释为什么我收到上述错误消息?

#!/bin/bash

FIND_DIRECTORIES=$(find . -type d -maxdepth 1 -mindepth 1)
FIND_IN_DIRECTORIES=$(find $FIND_DIRECTORIES"/app/design/adminhtml" -name "login.phtml")

for i in $FIND_IN_DIRECTORIES
  do
    # Generate Random Number
    RANDOM=$[ ( $RANDOM % 1000 )  + 1 ]

    # Find the line where password is printed out on the page
    # Grep for the whole line, then remove all but the numbers
    # This will leave the old password number
    OLD_NUM_HOLDER=$(cat $i | grep "<?php echo Mage::helper('adminhtml')->__('Password: ')" )
    OLD_NUM="${OLD_NUM_HOLDER//[!0-9]}"

    # Add old and new number to the end of text string
    # Beginning text string is used so that sed can find
    # Replace old number with new number
    OLD_NUM_FULL="password\" ?><?php echo \""$OLD_NUM
    NEW_NUM_FULL="password\" ?><?php echo \""$RANDOM
    sed -ie "s/$OLD_NUM_FULL/$NEW_NUM_FULL/g" $i

    # GREP for the setNewPassword function line
    # GREP for new password that has just been set above
    SET_NEW_GREP=$(cat $i | grep "setNewPassword(" )
    NEW_NUM_GREP=$(cat $i | grep "<?php echo \"(password\" ?><?php echo" )
    NEW_NUM_GREPP="${NEW_NUM_GREP//[!0-9]}"

    # Add new password to string for sed
    # Find and replace old password for setNewPassword function
    FULL_NEW_PASS="$user->setNewPassword(password"$NEW_NUM_GREPP")"
    sed -ie "s/$SET_NEW_GREP/$FULL_NEW_PASS/g" $i
  done

Thanks in advance for any help with this.

在此先感谢您的帮助。

UPDATE -- ANSWER

更新 - 答案

The issue here was that the for loop was not working as expected. I thought that it was doing /first/directory"/app/design/adminhtml" looping through and then doing /second/directory"/app/design/adminhtml" and then looping through. It was actually doing /first/directory looping through and then doing /second/directory"/app/design/adminhtml" and then looping through. So it was actually attaching the full directory path to the last item in the iteration. I have fixed the issue in the script below:

这里的问题是 for 循环没有按预期工作。我认为它正在执行 /first/directory"/app/design/adminhtml" 循环,然后执行 /second/directory"/app/design/adminhtml" 然后循环。它实际上是在执行 /first/directory 循环,然后执行 /second/directory"/app/design/adminhtml" 然后循环。所以它实际上是将完整的目录路径附加到迭代中的最后一项。我已经在下面的脚本中解决了这个问题:

#!/bin/bash

for i in $(find . -type d -maxdepth 1 -mindepth 1); do
  FIND_IN_DIRECTORIES=$i"/app/design/adminhtml/default"
  FIND_IN_DIRECTORIES=$(find $FIND_IN_DIRECTORIES -name "login.phtml")

  # Generate Random Number
  RANDOM=$[ ( $RANDOM % 1000 ) + 1 ]

  # Find the line where password is printed out on the page
  # Grep for the whole line, then remove all but the numbers
  # This will leave the old password number
  OLD_NUM_HOLDER=$(cat $FIND_IN_DIRECTORIES | grep "<?php echo Mage::helper('adminhtml')->__('Password: ')" )
  OLD_NUM="${OLD_NUM_HOLDER//[!0-9]}"

  # Add old and new number to the end of text string
  # Beginning text string is used so that sed can find
  # Replace old number with new number
  OLD_NUM_FULL="password\" ?><?php echo \""$OLD_NUM
  NEW_NUM_FULL="password\" ?><?php echo \""$RANDOM
  sed -ie "s/$OLD_NUM_FULL/$NEW_NUM_FULL/g" $FIND_IN_DIRECTORIES

  # GREP for the setNewPassword function line
  # GREP for new password that has just been set above
  SET_NEW_GREP=$(cat $FIND_IN_DIRECTORIES | grep "setNewPassword(" )
  NEW_NUM_GREP=$(cat $FIND_IN_DIRECTORIES | grep "<?php echo \"(password\" ?><?php echo" )
  NEW_NUM_GREPP="${NEW_NUM_GREP//[!0-9]}"

  # Add new password to string for sed
  # Find and replace old password for setNewPassword function
  FULL_NEW_PASS="$user->setNewPassword(password"$NEW_NUM_GREPP")"
  sed -ie "s/$SET_NEW_GREP/$FULL_NEW_PASS/g" $FIND_IN_DIRECTORIES
done

回答by shellter

without debugging your whole setup, note that you can use an alternate character to delimit sed reg-ex/match values, i.e.

无需调试整个设置,请注意,您可以使用备用字符来分隔 sed reg-ex/match 值,即

 sed -i "s\@$OLD_NUM_FULL@$NEW_NUM_FULL@g" $i

and

 sed -i "s\@$SET_NEW_GREP@$FULL_NEW_PASS@g" $i

You don't need the -e, so I have removed it.

您不需要 -e,所以我已将其删除。

Some seds require the leading '\' before the @, so I include it. It is possible that some will be confused by it, so if this doesn't work, try removing the leading '\'

某些 sed 需要在 @ 之前使用前导“\”,因此我将其包含在内。有些人可能会对此感到困惑,所以如果这不起作用,请尝试删除前导的 '\'

you should also turn on shell debugging, to see exactly which sed (and what values) are causing the problem. Add a line with set -vxnear the top of your script to turn on debugging.

您还应该打开 shell 调试,以准确查看导致问题的 sed(以及哪些值)。set -vx在脚本顶部附近添加一行以打开调试。

I hope this helps.

我希望这有帮助。