【问题标题】:How to use sed or awk command to set a variable based on the values of two other variables如何使用 sed 或 awk 命令根据其他两个变量的值设置变量
【发布时间】:2017-07-20 16:01:42
【问题描述】:

我正在尝试编写一个 bash 脚本,该脚本将在 conf 文件中查找过时的条目并使用新值更新它们。

旧的 conf 文件将有两个条目(-CAR 和 -BIKE)。例如,

#Following are the entries in the conf file
#-CAR yes/no default set to no
#-BIKE yes/no default set to no    

-CAR yes
-BIKE no

现在这个 bash 脚本应该对这些条目进行 grep 并将它们替换为单个条目作为 -DRIVING_LEVEL (car/bike/none)。

逻辑如下: 如果 -CAR 设置为 yes,则 DRIVING_LEVEL 将为“汽车”。 如果 -CAR 设置为 no 并且 -BIKE 设置为 yes,则 DRIVING_LEVEL 将是“自行车”。 如果 -CAR 和 -BIKE 都设置为 none,则 DRIVING_LEVEL 将为“none”。

我已经编写了下面的脚本,它可以做到这一点。

#!/bin/bash
CONF_FILE="license.conf"

grep -w $CONF_FILE -e '-CAR' -e '-BIKE'  > /dev/null
if [ $? -eq 0 ]
then
        echo "Old values are present"
        var=$(grep -w $CONF_FILE -e '-CAR')
        if [ $? -eq 0 ]
        then
                temp="${var##*$'\n'}"
                option=$(echo $temp | sed 's/.* //g')
                echo $option
                if [ "$option" == "yes" ]; then
                        car=1
                elif [ "$option" == "no" ]; then
                        car=0
                fi
                echo "Deleting $var"
                sed -i '/-CAR/d' $CONF_FILE
        fi

        var2=$(grep -w $CONF_FILE -e '-BIKE')
        if [ $? -eq 0 ]
        then
                temp2="${var2##*$'\n'}"
                option=$(echo $temp2 | sed 's/.* //g')
                echo $option
                if [ "$option" == "yes" ]; then
                        bike=1
                        #echo $temp
                elif [ "$option" == "no" ]; then
                        bike=0
                fi
                echo "Deleting $var2"
                sed -i '/-BIKE/d' $CONF_FILE
        fi

        if [ "$car" == "1" ]; then
                driving_level="car"
        elif [ "$bike" == "1" ]; then
                driving_level="bike"
        else
                driving_level="none"
        fi

echo "Appending -DRIVING_LEVEL $driving_level"
echo "-DRIVING_LEVEL $driving_level" >> $CONF_FILE
else
        echo "No old values"
fi

问题是我认为这太长了,可以使用 sed 或 awk 命令缩短。但我做不到。我希望它尽可能短。

提前致谢!

注意:

  • 我使用 temp="${var##*$'\n'}" 来检索具有实际值的最后一行,因为 grep 将给出包含-自行车。

  • 我使用了 option=$(echo $temp | sed 's/.* //g'),因为 -BIKE 和 yes/no 之间可以有任意数量的空格.

【问题讨论】:

  • 感谢您在这里展示您的努力,能否请您也展示此逻辑和示例 Input_file 的预期输出,也请分享到您的帖子中。
  • @RavinderSingh13 感谢您的回复。输入文件将类似于我在问题中提到的。输出应该是 conf 文件应该只包含 -DRIVING_LEVEL 条目,该条目将被设置为 car、bike 或 none。希望能回答你的问题!

标签: linux bash shell awk sed


【解决方案1】:
$ awk '($0 ~ /-CAR.*yes$/){dl="car";exit} ($0 ~ /-BIKE.*yes$/){dl="bike"} END{print "-DRIVING_LEVEL",(dl)?dl:"none"}' license.conf
-DRIVING_LEVEL car

简要说明,

  • $0 ~ /-CAR.*yes$/:如果找到“-CAR yes”,直接打印结果(这就是我在这里使用exit的原因)
  • ($0 ~ /-BIKE.*yes$/):如果找到“-BIKE yes”,继续寻找后续行,因为有可能找到“CAR”。
  • 如果没有找到,则将结果打印为“none”。

【讨论】:

  • 我还有一个疑问。我想删除 -BIKE 和 -CAR 的旧条目。现在我通过两次使用 sed 命令来做到这一点。 sed -i '/-BIKE/d' license.conf sed -i '/-CAR/d' license.conf 有没有更好更清洁的方法?
  • awk不是修改文件的工具,除非你能接受本帖中的方法stackoverflow.com/questions/37795186/…,那么我可以给你awk的解决方案
  • 我自己找到的。 sed -i '/-CAR\|-BIKE/d' license.conf
【解决方案2】:

您的整个脚本可以是:

awk '1; /^-CAR/ && $2 == "yes" {DL="car"} /^-BIKE/ && $2 == "yes" {DL="bike"}
  END{print "-DRIVING_LEVEL", DL}' DL=none license.conf

这只是在末尾附加一个 DRIVING_LEVEL 值(请注意,如果汽车和自行车都是“是”,这将选择文件中的最后一个,但您没有指定在这种情况下您想要什么行为。 ) 如果要抑制原始值的输出:

awk '/^-CAR/ && $2 == "yes" {DL="car"} /^-BIKE/ && $2 == "yes" {DL="bike"}
  ! (/^-CAR/ || /^-BIKE/)
  END{print "-DRIVING_LEVEL", DL}' DL=none license.conf

要检查原始条目是否存在,您可以这样做:

awk '/^-CAR/{DL=($2 == "yes" ? "car" : "none"); next} 
     /^-BIKE/{ if(DL== "unset" || DL == "none"){DL=($2 == "yes" ?"bike":"none")} next}
  1
  END{
    if(DL=="unset") { print "missing values" > "/dev/stderr"; exit 1 }
      else
    print "-DRIVING_LEVEL", DL}' DL=unset license.conf

虽然如果缺少条目,这将在最终注意到并发出错误消息之前输出文件。预检查输入可能更干净。

【讨论】:

  • 非常感谢。但我也想删除 -BIKE 和 -CAR 的旧条目。最重要的是,只有在有旧条目时才需要这样做。它不应该每次都将新条目附加为“DRIVING_LEVEL none”!
  • 我的意思是,如果 -CAR 设置为 yes,那么无论 -BIKE 是什么,-DRIVING_LEVEL 都应该是“汽车”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多