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变量fi1
和fi2
=] 参数 </code> 和 <code>
,它们包含基于 1 的 字段索引 相对于文件 $file
中的行。
然后,在awk程序内部,fi1
和fi2
中存储的字段索引首先被使用原样(没有$
前缀)来打印它们自己的值,然后通过添加 $
来引用相应的输入行 fields(Awk 中的变量引用没有 $
前缀 - $
仅用于指代 字段 ).
#!/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
看到程序 - 但很快就会混淆,应该避免。
- 相反,将值 back 从
awk
传递到 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
包含 数字 (计数) 的输入字段。
我想获取位置参数作为我的 .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变量fi1
和fi2
=] 参数 </code> 和 <code>
,它们包含基于 1 的 字段索引 相对于文件 $file
中的行。
然后,在awk程序内部,fi1
和fi2
中存储的字段索引首先被使用原样(没有$
前缀)来打印它们自己的值,然后通过添加 $
来引用相应的输入行 fields(Awk 中的变量引用没有 $
前缀 - $
仅用于指代 字段 ).
#!/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
看到程序 - 但很快就会混淆,应该避免。 - 相反,将值 back 从
awk
传递到 shell 的唯一方法是让 awk 打印到标准输出并使用 shell 命令替换以在 shell 变量中捕获结果。
- 通过访问
- 您可以使用
-v
选项的实例将 shell 参数和变量 的值传递给 awk 变量 ,如上所示。- 这里我们知道值是数字,所以我们并不严格需要对 var 进行双引号。参考文献,但一般来说它是可取的。
- 在
awk
里面,它的变量被引用没有$
前缀,$
是仅用于引用输入字段:$fi1
,可能有点令人困惑,因此意思是:获取输入字段(前缀$
),其索引存储在awk
variablefi1
(相比之下,按原样使用fi1
,没有前缀,return index).
awk
中的字段索引始终基于 1,相对于每行输入。- 例如,在
awk
中,</code> 指的是当前输入行 <em> 的第一个字段 </em>,即使它 <em>看起来</em>与<em>shell</em>中的第一个脚本/函数参数相同,它们完全没有任何关系。</li> <li>此外,<code>[=44=]
包含 整个 当前输入行,NF
包含 数字 (计数) 的输入字段。
- 例如,在