【问题标题】:error in awk of shell scriptshell脚本的awk错误
【发布时间】:2013-05-09 03:41:00
【问题描述】:

我的代码出现以下错误。其中缺少什么?我的目标是在 $version 中打印 13.0.5.8

 #!/bin/ksh

 file="abc_def_APP_13.0.5.8"
  if echo "$file" | grep -E "abc_def_APP"; then
        echo "Version found: $file"

    version1=(echo $file |  awk -F_ '{print $NF}' | cut -d. -f1-3)

    version2=(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)

    echo $version1

    echo $version2

        version=$version$version2

        echo $version
 else
       echo "Version not found"
  fi

请在下方查找错误:

 ./version.sh: line 7: syntax error near unexpected token `|'
./version.sh: line 7: ` version1=(echo $file |  awk -F_ '{print $NF}' | cut -d. -f1-3)'
./version.sh: line 9: syntax error near unexpected token `|'
./version.sh: line 9: ` version2=(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)'



./version.sh: line 18: syntax error near unexpected token `else'

【问题讨论】:

    标签: shell awk grep


    【解决方案1】:

    根本不需要 awk。只需修剪最后一个下划线之前的每个字符,如下所示:

    file="abc_def_APP_13.0.5.8"
    version="${file##*_}"
    echo "$version"
    

    有关此技术的文档,请参阅 http://mywiki.wooledge.org/BashFAQ/073,或参阅 bash 自己的文档中的“参数扩展”。

    单独处理最后一段也很简单:

    file="abc_def_APP_13.0.5.8"
    version="${file##*_}"          # result: 13.0.5.8
    version_end="${version##*.}"   # result: 8
    version_start="${version%.*}"  # result: 13.0.5
    echo "${version_start}/${version_end}" # result: 13.0.5/8
    

    因为这发生在 bash 内部,无需执行任何外部命令(例如 awk),它的执行速度应该比给定的其他方法快得多。

    【讨论】:

    • 这很好用,但我希望我的版本变量值为13.0.5/8 抱歉,因为我一开始的问题并不清楚。我怎样才能实现它?
    • @sravs448 已适当更新。
    • @AdrianFrühwirth 为什么这是公认的答案?问题是关于 OP 看到的错误,答案是反引号中缺少 $。这是实现相同目标的一种很好的替代方法,但它实际上并不能回答问题。
    • @sudo_O 如果有人问他们为什么不能用筛子装水,最好的答案是告诉他们如何使用水桶,而不是建议他们用粘土塞住筛子。
    【解决方案2】:

    问题是你的反引号丢失$ 你需要像这样修复以下两行:

    version1=$(echo $file |  awk -F_ '{print $NF}' | cut -d. -f1-3)
    
    version2=$(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)
    

    这将修复语法错误。以下行没有多大意义,因为 $version 尚未初始化:

    version=$version$version2
    

    你的意思是:

    version="${version1}.${version2}"
    

    附注您正在使用-E 选项和grep,但您没有使用任何扩展的正则表达式功能,实际上您正在执行固定字符串搜索,因此-F 更合适。您可能还想使用-q 选项来抑制grep 的输出。

    我个人会这样做:

    file="abc_def_APP_13.0.5.8"
    
    echo "$file" | awk '/abc_def_APP/{print "Version found: "$0;
                                      print $4,$5,$6;
                                      print $7;
                                      print $4,$5,$6,$7; 
                                      next}
                        {print "Version not found"}' FS='[_.]' OFS=.
    

    如果您只想要变量 version 中的版本号,那么为什么不简单:

    version=$(echo "$file" | grep -o '[0-9].*')
    

    【讨论】:

    • 这似乎相当脆弱。你怎么知道abc_def_APP以后不会是abc_def_foo_APP
    • 我当然不知道。我只知道OP给出的问题中的信息。我的回答是唯一指出脚本失败原因的人,我建议的 awk 解决方案只是对 OP 已有内容的直接翻译,因此与他的原始解决方案一样脆弱。
    【解决方案3】:

    这一切都可以在一个 awk 命令中完成,无需额外的 cut 命令。考虑以下命令:

    read version1 version2 < <(echo $file|awk -F "[_.]" '{
       printf("%s.%s.%s ", $4, $5, $6); printf("%s", $7);
       for (i=8; i<=NF; i++) printf(".%s", $i); print ""}')
    
    echo "$version1 :: $version2"
    

    输出

    13.0.5 :: 8
    

    【讨论】:

    • 我在另一个文件中有一行具有不同的版本号。我想在那里替换这个版本号。 File1: location="/path/13.2.0/9/application1.war" 如何将13.2.0/9 替换为我们从上面代码中获得的$version1/$version2。我有一个代码来获取文件中的旧版本号。 VERSION=($(grep -r "location=.*war" /path/filename | awk '{print ($1)}'| cut -f8- -d"/"|sed 's/.\{1\}$//')) 这给了我一个旧版本号 13.2.0/9 的输出
    • 你可以使用这个awk:awk -v v1=$version1 -v v2=$version2 'BEGIN {FS=OFS="/"} {$3=v1; $4=v2;}'1 /path/filename
    • 它没有改变文件中的任何内容。这个 awk 应该用新版本号替换旧版本号吗?
    • 是的,它将用新版本替换您的旧版本。您的文件具有以下内容权利:location="/path/13.2.0/9/application1.war?
    • 这是一个非常大的文件,包含许多应用程序详细信息。我想在location="cc://view/blah/blah/blah/abc_def_APP/13.2.0/9/application1.war" 这一行替换一个特定应用程序的版本号,所有应用程序都有自己的版本号。这就是为什么在我上面的 awk 命令中,我专门为 location=.*application1.war 做了一个 grep
    猜你喜欢
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多