【问题标题】:awk command to accept two variables as parameters and return a valueawk 命令接受两个变量作为参数并返回一个值
【发布时间】:2009-10-14 21:17:57
【问题描述】:

我有一个有 50 行的文件。每行由三列组成。前两列是变量,这将作为参数传递以返回第三列的值。 例如.. command_file.txt 是文件,它包含

A B 10 光盘 20 英法 30 GH 50 我 J 70 ...

我有一个包含以下命令的脚本。

#!/user/bin/sh READ_FILE=/export/home/user/command_file.txt VA1=A VA2=B GET_VALUE=`awk '/ -v var="$VA1" '$1 ~ var' -v var1="$VA2" '$1 ~ var1''/ $READ_FILE l awk '{print $3}'` 回显 $GET_VALUE

当我调用这个脚本传递 A 和 B 作为参数时,我希望返回值 10。但它返回了错误。 但是,如果我在下面的命令中硬编码该值,它将起作用。

GET_VALUE=`awk '/A B'/ $READ_FILE lawk '{print $3}'`

有什么建议吗? 谢谢。

【问题讨论】:

  • 你为什么不告诉我们你得到的错误;)
  • cheri,你需要学习管道字符|和小写字母“ell”的区别,以及如何正确使用引号(单引号和双引号)。一个基本的 shell 教程会有所帮助。

标签: awk unix


【解决方案1】:

您必须在 awk 脚本开始之前使用 awk's 变量传递以避免毛茸茸的引用,并修复其他问题:

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=$(awk -v var="$VA1" -v var1="$VA2" '$1 ~ var &&  $2 ~ var1 {print $3}' $READ_FILE)
echo $GET_VALUE

【讨论】:

  • 请注意,这仍然有 OP 的错字,在 echo 命令中缺少 $。
【解决方案2】:

抱歉,我无法确定您的脚本正在尝试做什么,因此无法正确调试它。我想也许你有嵌套引号或其他事情。

我认为下面的单线会做你想要的。

#!/bin/bash
grep "^$1 $2" /export/home/user/command_file.txt | awk '{print $3}'

编辑

好的,感谢其他人指出您尝试使用 -v 选项做什么。

您的代码在 echo GET_VALUE 命令中缺少 $,并且您有一个字母 l 而不是竖线 |。另外还有其他错别字。

我认为这可行

READ_FILE=/export/home/user/command_file.txt
awk -v var1=$1 -v var2=$2 '$1 ~ var1 && $2 ~ var2; /^var1 var2/' $READ_FILE | awk '{print $3}'

但我更喜欢上面的 grep 命令,因为它不需要额外的努力就可以将命令行变量传递给 awk。

【讨论】:

  • /^var1 var2/ 是多余的,而“;”在打印每个输入行之前进行匹配(因为分号之前没有任何操作)。
  • 另外,第二次将其通过管道传输到 awk 是不必要的。它可以在第一次获得该字段时打印该字段。
  • 丹尼斯威廉姆森,谢谢。好渔获。我可能应该只用 grep 坚持我的原始版本。无论如何,我认为这是更好的方法。
【解决方案3】:

我想这就是你要找的东西:

#!/user/bin/sh
READ_FILE=/export/home/user/command_file.txt
VA1=A
VA2=B
GET_VALUE=`awk -v var1=$VA1 -v var2=$VA2 '$1==var1 && $2==var2 {print $3}' command_file.txt `
echo $GET_VALUE

【讨论】:

    【解决方案4】:

    或许:

    #!/bin/bash
    grep "$1" test.txt | grep "$2" | awk '{print $3}'
    

    如果您的变量需要按任意顺序排列?

    【讨论】:

    • $1$2 在此上下文中是 awk 字段,而不是位置参数。相关变量为$VA1$VA2
    【解决方案5】:

    固定:

    #!/user/bin/sh
    READ_FILE=/export/home/user/command_file.txt
    VA1=A
    VA2=B
    GET_VALUE=`awk "/$VA1 $VA2/ "'{print $3}' < $READ_FILE`
    echo $GET_VALUE
    

    【讨论】:

    • 最好用-v 传入变量,而不是用引号来耍花招。
    • @glenn:嗯?定义“更好”?它肯定不是更漂亮
    • @rosenfield:不需要重定向输入文件; awk 接受文件名作为参数。此外,正确引用可能会很快变得棘手。它可能不漂亮,但-v 是可靠的。出于类似原因,最好避免使用反引号。
    • @dennis:输入文件:是的,谢谢。重要的是,性能方面吗? quoting:看不出可靠性是个问题;我还发现上面使用的引用非常容易阅读,但确实需要练习(即你需要知道 shell 引用是如何工作的!)
    • @rosenfield,在 VA1 等具有已知值的情况下,如这里,引用很好。但如果事实证明 VA1 可能包含 foo/{next} /bar,你会希望你已经养成使用 -v 的习惯。
    【解决方案6】:

    我知道这是一篇旧帖子,但 awk 更老且仍在使用 - 人们仍在寻找相同的答案。我想我就是一个例子。

    我决定实现一个类似的场景,但想要在配置文件中预定义变量。用户将配置文件的部分名称作为第一个参数传递给脚本。

    cfg=$PWD/$1.cfg
    
    foo=$(awk '$1 ~ /foo/ { print $2 }' $cfg)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-27
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多