我将以下脚本保存在 中bin
,它用于根据定义的变量获取输出。目前,该脚本正在针对第 1 列运行并提供输出。我们如何更新此脚本,以便它可以在与第 1 列或第 2 列匹配时提供输出。
cat ~/bin/POUT
#!/bin/bash
exec awk -v arg=${1:?} '$1==arg' "${@:2}" inputfile
输入文件-:
DEV RETAIL RETAILDEVNode
TEST RETAILTEST RETAILTESTNode
TEST AUDIT AUDITTESTNode
QA AUDITQA AUDITQANode
PROD SALE SALEPRODNode
QA SALEQA SALETESTNode
QA FINANCE FINANCEQANode
PROD FINANCE FINANCEPRODNode
目前正在获得预期输出-
$ POUT QA
QA AUDITQA AUDITQANode
QA SALEQA SALETESTNode
QA FINANCE FINANCEQANode
还想要如下输出(也在第 2 列中搜索):
$ POUT AUDITQA
QA AUDITQA AUDITQANode
Want output like this also (put any matching value and search in column 2 aslo) ---
$ POUT DITQ
QA AUDITQA AUDITQANode
因此,无论变量中给出什么输入,它都应该在第 1 列和第 2 列中进行搜索并提供输出。
答案1
#!/bin/bash
arg="${1:?}" # Capture argument value or fail
shift
awk -v arg="${arg//\\/\\\\}" 'index($1, arg) || index($2, arg)' "$@" inputfile
使用 shell 变量时始终用双引号引起来。 (始终如此,直到您理解为什么偶尔会有例外。在此之前始终使用双引号。)
$arg
shell变量对awk
变量的乱赋值arg
是为了undoawk
的反斜杠处理。
我不明白为什么您要将剩余的命令行参数传递给awk
和inputfile
作为持续来源提供。不过,我还是保留了它,以防万一这是故意的。
答案2
可能:
#! /bin/sh -
export ARG="${1?}"
shift
exec awk '
BEGIN{
field = 1
arg = ENVIRON["ARG"] ""
}
$field == arg' "$@" inputfile
然后您可以调用它来在第二个字段中POUT AUDITQA field=2
查找,AUDITQA
同时保持 CLI 向后兼容性。
一些注意事项:
- 如果您忘记了 bash 或 sh 中的扩展的引号,就像您的 中一样
-v arg=${1?}
,它们将受到 split+glob 的影响。这里非常糟糕,因为这引入了任意命令执行漏洞。这实际上是给出的例子之一忘记在 bash/POSIX shell 中引用变量的安全隐患 - 您不能使用mangles 反斜杠
-v
来传递任意文本-v
。因此使用ENVIRON
上面的方法就没有问题。 - 请注意,由于
awk
将foo=bar.txt
参数视为变量赋值,因此如果您的文件名包含=
字符,则需要将它们传递为./foo=bar.txt
而不是foo=bar.txt
. $field
和ENVION["var"]
/或通过传递的变量-v
如果看起来是数字,则被视为数字字符串,并且==
最终可能会进行数字比较而不是字符串比较。我们连接""
toENVIRON["ARG"]
以便始终将其视为字符串,因此,例如,如果使用10
参数调用,则它与 10.0 或 010 或 1e1 不匹配。