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
Bash script 'sed: first RE may not be empty' error
提问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.
我希望这有帮助。

