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

Columns and Arguments AWK Parameters in Shell Scripting

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

例如我这样称呼我的 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=""

awk -F'[:,]' -v u1= -v v1= -v u2= -v v2= \ '{ print "u1 =", $u1 }' 
awk -F'[:,]' -v u1= -v v1= -v u2= -v v2= \ '{ print "v1 =", $v1 }' 
awk -F'[:,]' -v u1= -v v1= -v u2= -v v2= \ '{ print "u2 =", $u2 }' 
awk -F'[:,]' -v u1= -v v1= -v u2= -v v2= \ '{ print "v2 =", $v2 }' 

echo "Argument #1 =" 
echo "Argument #2 =" 
echo "Argument #3 =" 
echo "Argument #4 =" 

这是我从终端获得的输出:

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 脚本在各个领域走得更远?

更新:OP的问题似乎源于对shell参数</code>, <code>, ...) 在 Awk 中带有 输入字段 变量 - 可以 相同,但完全无关。
具体来说,错误的假设是如果 n 参数被传递给 shell 脚本,Awk 的输入-字段编号将以 n+1.

开头

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

具体是根据shell[=110的值定义Awk变量fi1fi2 =] 参数 </code> 和 <code>,它们包含基于 1 的 字段索引 相对于文件 $file 中的行。

然后,在awk程序内部,fi1fi2中存储的字段索引首先被使用原样(没有$前缀)来打印它们自己的值,然后通过添加 $ 来引用相应的输入行 fieldsAwk 中的变量引用没有 $ 前缀 - $ 仅用于指代 字段 ).

#!/usr/bin/env bash

file=""

awk -F'[:,]' -v fi1= -v fi2= \
  '{ print "Field #" fi1 " + field #" fi2 " =", $fi1 + $fi2 }' "$file"
  • shell和awk是不同的世界,看不到彼此的变量。
    • 通过访问ENVIRON关联数组,可以在awk中看到环境变量,但是看不到shell 个变量。
    • 可以 隐式地 "bake" shell 变量值到 awk 程序通过传递 双引号 带有 shell 变量引用的字符串 - 在 之前 awk 看到程序 - 但很快就会混淆,应该避免。
    • 相反,将值 backawk 传递到 shell 的唯一方法是让 awk 打印到标准输出并使用 shell 命令替换以在 shell 变量中捕获结果。
  • 您可以使用 -v 选项的实例将 shell 参数和变量 的值传递给 awk 变量 ,如上所示。
    • 这里我们知道值是数字,所以我们并不严格需要对 var 进行双引号。参考文献,但一般来说它是可取的。
  • awk里面,它的变量被引用没有$前缀,$用于引用输入字段
    • $fi1,可能有点令人困惑,因此意思是:获取输入字段(前缀$),其索引存储在awk variable fi1(相比之下,按原样使用 fi1,没有前缀,return index).
  • awk 中的字段索引始终基于 1,相对于每行输入。
    • 例如,在 awk 中,</code> 指的是当前输入行 <em> 的第一个字段 </em>,即使它 <em>看起来</em>与<em>shell</em>中的第一个脚本/函数参数相同,它们完全没有任何关系。</li> <li>此外,<code>[=44=] 包含 整个 当前输入行,NF 包含 数字 (计数) 的输入字段。