且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

AWK多个字段分隔符和变量

更新时间:2022-12-11 22:11:24

当您在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"