Shell脚本中的列和参数AWK参数

时间:2015-03-30 01:28:08

标签: bash unix awk arguments sh

我想获取位置参数作为我的.sh文件的参数,我也希望从awk的文本文件中获取字段。我已经发现我需要使用$ 1- $ 9两者并且可以在awk中使用相同的数字$()作为定位参数,它仍然有效。

e.g。我像这样调用我的shell脚本

./myProgram myFile.txt 1 2 3 4

然后在我的shell脚本中,我想使用awk来引用这样的文本文件中的字段,特别是1,2:3,4最后四个字段。

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脚本进一步跨越这些领域?

1 个答案:

答案 0 :(得分:3)

更新:似乎OP的问题源于对 shell参数$1$2之间区别的混淆,...... ) awk 中的输入字段变量 - 它们看起来相同,但完全不相关。
具体来说,不正确的假设是,如果n参数传递给 shell 脚本, Awk 的输入字段编号将以{{1}开头}。


以下片段 - 最初是在OP之前编写的,为问题添加了更多代码 - 演示了shell参数和 Awk 变量的相互作用,然后是详细解释。< / p>

具体来说,它根据 shell 参数n+1和{{1}的值定义 Awk 变量fi1fi2分别包含相对于文件$2中的行的基于1的字段索引

然后,在Awk程序中,$3$file中存储的字段索引首先使用 (无fi1前缀)来打印它们自己的值,然后通过前置fi2引用相应的输入行字段 Awk 中的变量引用不是$ - 前缀 - $仅用于引用字段)。

$
  • shell和$是不同的世界,并没有看到彼此的变量。
    • 您可以通过访问#!/usr/bin/env bash file="$1" awk -F'[:,]' -v fi1=$2 -v fi2=$3 \ '{ print "Field #" fi1 " + field #" fi2 " =", $fi1 + $fi2 }' "$file" 关联数组,在awk中看到 environment 变量,但是您看不到 shell 变量。
    • 可以通过传递带有shell变量引用的双引号字符串,将shell变量值隐式“烘焙”到awk程序中在 ENVIRON看到程序之前扩展 - 但这很快就会引起混淆,应该避免。
    • 相反,将值返回awk传递给shell的唯一方法是将awk打印到stdout并使用shell命令替换来捕获shell变量中的结果。
  • 您可以使用awk选项的实例将shell参数和变量的值传递给awk变量,如上所示。
    • 这里我们知道值是数字,所以我们不需要严格地引用var。引用,但一般来说这是可取的。
  • awk内,其变量引用而不 -v前缀,而awk 用于参考输入字段
    • $,或许有些令人困惑,因此意味着:获取输入字段(前缀$),其索引存储在$fi1 变量< / em> $(相比之下,使用awk,没有前缀,将返回索引)。
  • 相对于每一行输入,fi1中的字段索引始终 1 为基础
    • 例如,在fi1内,awk指的是当前输入行上的第一个字段,即使它看起来相同作为 shell 中的第一个脚本/函数参数,它们完全没有任何关系。
    • 此外,awk包含整个当前输入行,$1包含输入字段的数字(计数)。