我正在尝试使用从shell传入数字的字段以及最后四个字段在awk中执行计算
e.g。我像这样调用我的shell脚本
./myProgram myFile.txt 1 2 3 4
然后在我的shell脚本中,我想使用awk
来引用像这样的文本文件中的字段,特别是最后四个字段。 $(NF-3) - $(NF)
0000000022:trevor:736:1,2:3,4
0000000223:john:73:5,6:7,8
0000002224:eliza:54:9,8:7,6
0000022225:paul:22:5,4:3,2
0000222226:chris:0:1,2:3,4
所以我可以浏览这些字段,但是当我这样做时,因为有两种类型的字段分隔符,它似乎无法工作。
到目前为止我的shell脚本:
#! /usr/bin/env bash
file="$1"
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "u1 =", $u1 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "v1 =", $v1 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "u2 =", $u2 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "v2 =", $v2 }' $1
echo "Argument #1 =" $2
echo "Argument #2 =" $3
echo "Argument #3 =" $4
echo "Argument #4 =" $5
这是我从终端获得的输出:
u1 = 1
u1 = 5
u1 = 9
u1 = 5
u1 = 1
v1 = awk: illegal field $(), name "v1"
input record number 1, file database.txt
source line number 1
u2 = awk: illegal field $(), name "u2"
input record number 1, file database.txt
source line number 1
v2 = awk: illegal field $(), name "v2"
input record number 1, file database.txt
source line number 1
Argument #1 = 1
Argument #2 = 2
Argument #3 = 3
Argument #4 = 4
答案 0 :(得分:1)
在awk中使用$N
时,它会检索字段N
。您可以将此参数与为awk传递参数结合使用,就像访问shell变量中定义的字段编号一样。主要问题似乎是您传递的是尚未在脚本中设置的变量。
在脚本的示例调用中,您没有为位置参数$6
及其上面传递足够的参数来定义。这导致您的错误消息看起来像illegal field $()
,因为v1
是一个空字符串,因此您尝试获取没有数字的字段。
NF
是awk中包含字段数量的特殊变量,因此要访问最后四个字段,您可以使用$(NF-3)
,$(NF-2)
,$(NF-1)
,和$NF
。
在awk命令之前有一个\
并没有做任何有用的事情,所以我也删除了它。
您的代码还有其他一些问题值得一提。引用你的shell变量!这可以防止在更复杂的变量上进行单词拆分的问题。如果你的论点是没有空格的数字,这不会有任何区别,但它也没有任何伤害,并且是一个很好的做法。您已定义file
,因此我使用了$1
而不是awk -F'[:,]' -v u1="$2" -v v1="$3" -v u2="$4" -v v2="$5" '{ print "u1 =", u1 }' "$file"
。
结合这些变化,我们最终会得到这样的结果:
{{1}}
答案 1 :(得分:0)
大约一行:
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "u1 =", $u1 }' $1
这里$ 5,$ 6,$ 7和$ 8是bash位置参数而不是awk字段位置。 根据命令行,您在脚本中有5个参数:
./myProgram myFile.txt 1 2 3 4
$1 = myFile.txt
$2 = 1
$3 = 2
$4 = 3
$5 = 4
$6 =
$7 =
$8 =
这就是为什么awk仅在通知$v1
时提醒您,因为它等同于$
并且不是字段值。
如果我理解你的问题,你希望获得最后4个参数匹配值的行:
awk -F'[:,]' '{ print "u1=",$(NF-3),"v1=",$(NF-2),"u2=",$(NF-1),"v2=",$NF }' "$1"
NF是字段数,减3表示结束前的4字段。