AWK多个字段分隔符和变量 [英] AWK Multiple Field Separators and Variables

查看:663
本文介绍了AWK多个字段分隔符和变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用执行其人数从外壳传递领域,以及最后四个字段AWK计算

例如。我把我的shell脚本这样

  ./ myProgram MYFILE.TXT 1 2 3 4

然后我的shell脚本中我想用 AWK 引用的字段在文本文件中这样的,特别是最后四场。 $(NF-3) - $(NF)

  0000000022:特雷弗:736:1,2:3,4
0000000223:约翰:73:5,6:7,8
0000002224:伊莉莎:54:9,8:7,6
0000022225:保罗:22:5,4:3,2
0000222226:克里斯:0:1,2:3,4

所以我可以顺利通过的字段,但是当我这样做,因为有两种类型的字段分隔符似乎不工作。

我的shell脚本至今:

 #!在/ usr /斌/ bash的ENV文件=$ 1awk的-F[:,]'-v U1 = $ 5 -v V1 = $ 6个-v U2 = $ 7 -v V2 = $ 8个\\'{打印U1 =$ U1}'$ 1
awk的-F[:,]'-v U1 = $ 5 -v V1 = $ 6个-v U2 = $ 7 -v V2 = $ 8个\\'{打印V1 =$ V1}'$ 1
awk的-F[:,]'-v U1 = $ 5 -v V1 = $ 6个-v U2 = $ 7 -v V2 = $ 8个\\'{打印U2 =$ U2}'$ 1
awk的-F[:,]'-v U1 = $ 5 -v V1 = $ 6个-v U2 = $ 7 -v V2 = $ 8个\\'{打印V2 =$ V2}'$ 1回声参数#1 =$ 2
回声参数#2 =$ 3
回声参数#3 =$ 4个
回声参数#4 =$ 5

这是输出,我从终端获取:

  U1 = 1
U1 = 5
U1 = 9
U1 = 5
U1 = 1
V1 = AWK:非法场$(),名称为V1
 输入记录号1,文件database.txt
 源代码行数1
U2 = AWK:非法场$(),名称为U2
 输入记录号1,文件database.txt
 源代码行数1
V2 = AWK:非法场$(),名称为V2
 输入记录号1,文件database.txt
 源代码行数1
参数#1 = 1
参数#2 = 2
参数#3 = 3
参数#4 = 4


解决方案

当您在AWK使用 $ N ,将检索字段 N 。您可以结合参数传递给AWK为你做访问shell变量定义的字段号使用。主要的问题似乎是要传递,但没有在脚本中设置的变量。

在脚本的例子调用,你没有足够的传递为参数 $ 6个及以上定义位置参数。这是什么原因造成,看起来像你的错误消息违法场$(),因为 V1 是一个空字符串,所以你试图获得一个字段没有数。

NF 是AWK一个特殊的变量,它包含的字段的数量,所以进入最后四场,​​你可以使用 $(NF -3) $(NF-2) $(NF-1) $ NF

有一个 \\ 这是没有做什么有用的东西awk命令之前,所以我删除这一点。

有几个与你的code,值得一提的太多等问题。注明您的shell变量!这prevents更复杂的变量与分词的问题。如果你的论点是数字没有空格,这不会使任何区别,但它要么没有伤害,是一个很好的做法进入。你已经定义文件,所以我使用的,而不是 $ 1

结合这些变化,我们最终是这样的:

 的awk -F[:,]'-v U1 =$ 2-v V1 =$ 3-v U2 =$ 4-v V2 =$ 5' {打印U1 =U1}'$文件

I am trying to perform calculations in awk using fields whose numbers are passed in from the shell, as well as the last four fields

e.g. I call my shell script like this

./myProgram myFile.txt 1 2 3 4

Then within my shell script I want to use awk to refer to fields in a text file like this, specifically the last four fields. $(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

So I can go through the fields, however when I do because there are two types of field separators it doesn't seem to work.

My shell script so far:

#! /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

This is the output I get from terminal:

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

解决方案

When you use $N in awk, it will retrieve field N. You can use this in combination with passing arguments to awk as you have done to access a field number defined in a shell variable. The main issue would appear to be that you are passing variables that haven't been set in your script.

In your example invocation of the script, you're not passing enough arguments for positional parameters $6 and above to be defined. This is what is causing your error messages that look like illegal field $(), because v1 is an empty string, so you're attempting to get a field with no number.

NF is a special variable in awk that contains the number of fields, so to access the last four fields, you can use $(NF-3), $(NF-2), $(NF-1), and $NF.

There was a \ before the awk command which wasn't doing anything useful, so I removed that as well.

There are a couple of other issues with your code that are worth mentioning too. Quote your shell variables! This prevents issues with word splitting on more complex variables. If your arguments are numbers with no spaces, this won't make any difference but it does no harm either and is a good practice to get into. You've defined file, so I've used that instead of $1.

Combining those changes, we end up with something like this:

awk -F'[:,]' -v u1="$2" -v v1="$3" -v u2="$4" -v v2="$5" '{ print "u1 =", u1 }' "$file"

这篇关于AWK多个字段分隔符和变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆