【问题标题】:Run a sed command depending on a variable根据变量运行 sed 命令
【发布时间】:2018-07-20 12:13:21
【问题描述】:

我正在尝试根据用户输入运行变量sed 命令:

#!/bin/bash

ACTION=$1

if [ "wp" == "$ACTION"  ]
then
   MODIFIEDCONF='sed -i -e "/#Begin wp redirect/,/#End wp redirect/d" /root/test-conf'
else
   MODIFIEDCONF='sed -i -e "/#Begin ghost redirect/,/#End ghost redirect/d" /root/test-conf'
fi

RESULT=$($MODIFIEDCONF)

但我得到了错误:

sed: -e expression #1, char 1: unknown command: `"'

如何修复错误?还是有更好的方法?

【问题讨论】:

  • 我不认为这是你问题的根源,但你的比较应该只有一个等号。 stackoverflow.com/questions/2237080/…
  • 为什么要创建变量?如果您想查看新编辑的文件,只需打印它?

标签: bash if-statement sed switch-statement


【解决方案1】:

保持简单。将你的 sed 命令模式设置在一个变量中,然后执行它。

case "$ACTION" in
wp) cmd="/#Begin wp redirect/,/#End wp redirect/d"       ;;
 *) cmd="/#Begin ghost redirect/,/#End ghost redirect/d" ;;
esac

sed -i "$cmd" /root/test-conf

或者为了提高可读性,只需设置密钥并嵌入。

case "$ACTION" in
wp) key=wp    ;;
 *) key=ghost ;;
esac

sed -i "/#Begin $key redirect/,/#End $key redirect/d" /root/test-conf

抽象就是力量,但不必要的抽象就是混淆。

【讨论】:

    【解决方案2】:

    尽量避免做变量扩展,即运行$var。如果您仅在脚本中使用变量,则使用小写字母时,仅使用 UPPERCASE_VARIABLES 导出变量是一种习惯。
    为什么不这样:

    #!/bin/bash
    
    # get action
    action=$1
    
    # check action value
    case "$action" 
    wp) ;;
    *) action=ghost; ;;
    # or maybe: *) echo "ERROR: action has bad value! Exiting!" >&2; exit 1; ;;
    esac
    
    # run sed
    result=$(sed -i -e "s/#Begin $action redirect/,/#End $action redirect/" /root/test-conf)
    

    如果你必须 result=$($modifiedconf) 使用 bash 数组:

    if [ "wp" = "$action" ]; then
       modifiedconf=(sed -i -e "/#Begin wp redirect/,/#End wp redirect/d" /root/test-conf)
    else
       modifiedconf=(sed -i -e "/#Begin ghost redirect/,/#End ghost redirect/d" /root/test-conf)
    fi
    result=$("${modifiedconf[@]}")
    

    【讨论】:

      【解决方案3】:

      使用函数来存储代码,而不是字符串。

      #!/bin/bash
      
      ACTION=$1
      
      if [ "wp" == "$ACTION"  ]
      then 
         modify_conf() { sed -i -e "/#Begin wp redirect/,/#End wp redirect/d" /root/test-conf; }
      else
         modify_conf() { sed -i -e "/#Begin ghost redirect/,/#End ghost redirect/d" /root/test-conf; }
      fi
      
      modify_conf
      

      (modify_conf 没有输出任何有用的东西,所以没有必要捕获它的输出。)

      或将ACTION 作为参数传递:

      modify_conf () {
        if [ "$1" = wp ]; then
          sed -i -e "/#Begin wp redirect/,/#End wp redirect/d" /root/test-conf
        else
          sed -i -e "/#Begin ghost redirect/,/#End ghost redirect/d" /root/test-conf
        fi
      }
      
      modify_conf "$ACTION"
      

      【讨论】:

        【解决方案4】:

        要删除您报告的错误,您应该更改行:

         RESULT=$($MODIFIEDCONF)
        

        到:

         eval "$MODIFIEDCONF"
        

        有关此内容和参考的更多详细信息,请参见例如:

        一个警告。命令eval 确实有一个bad 声誉:例如参见Why should eval be avoided in Bash, and what should I use instead?。但在这种情况下,它是完全安全的。 eval "$MODIFIEDCONF"(此处为可选)中的额外引号有助于防止出现意外错误。


        次要观点:您编写的sed 命令不会返回任何文本(可能对stderr 除外)。如果您确实需要变量 RESULT 的值,请添加以下行:

          RESULT=$?
        

        $RESULT 将始终为0,除非文件/root/test-conf 不存在(或者如果您的脚本碰巧有一个无效的sed 命令,这里不是这种情况)。

        【讨论】:

          猜你喜欢
          • 2021-07-01
          • 2012-12-12
          • 2017-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-16
          • 2012-06-24
          • 2012-02-15
          相关资源
          最近更新 更多