[英]AWK Multiple Field Separators and Variables
我正在尝试使用从外壳传递其数字的字段以及最后四个字段在awk中执行计算
例如,我这样称呼我的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
在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"
大约一行:
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个匹配thoose值的行:
awk -F'[:,]' '{ print "u1=",$(NF-3),"v1=",$(NF-2),"u2=",$(NF-1),"v2=",$NF }' "$1"
NF为字段数,负3表示末尾的4字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.