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

use*_*142 5 bash sed

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

尽管出现错误消息,脚本似乎工作正常并且正在正确地对文件进行更改。谁能帮助解释为什么我收到上面的错误消息?

#!/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
Run Code Online (Sandbox Code Playgroud)

预先感谢您对此提供的任何帮助。

更新——答案

这里的问题是 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
Run Code Online (Sandbox Code Playgroud)

she*_*ter 3

在不调试整个设置的情况下,请注意,您可以使用替代字符来分隔 sed reg-ex/匹配值,即

 sed -i "s\@$OLD_NUM_FULL@$NEW_NUM_FULL@g" $i
Run Code Online (Sandbox Code Playgroud)

 sed -i "s\@$SET_NEW_GREP@$FULL_NEW_PASS@g" $i
Run Code Online (Sandbox Code Playgroud)

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

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

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

我希望这有帮助。