简体   繁体   English

直接在AWK中设置BASH环境变量(在AWK单行中)

[英]Setting a BASH environment variable directly in AWK (in an AWK one-liner)

I have a file that has two columns of floating point values. 我有一个包含两列浮点值的文件。 I also have a C program that takes a floating point value as input and returns another floating point value as output. 我也有一个C程序,该程序将浮点值作为输入,并返回另一个浮点值作为输出。

What I'd like to do is the following: for each row in the original, execute the C program with the value in the first column as input, and then print out the first column (unchanged) followed by the second column minus the result of the C program. 我要执行的操作如下:对于原始行中的每一行,以第一列中的值作为输入执行C程序,然后打印出第一列(未更改),然后打印第二列减去结果C程序的代码。

As an example, suppose c_program returns the square of the input and behaves like this: 举例来说,假设c_program返回输入的平方并表现如下:

$ c_program 4 $ c_program 4
16 16
$ $

and suppose data_file looks like this: 并假设data_file看起来像这样:

1 10 1 10
2 11 2 11
3 12 3 12
4 13 4 13

What I'd like to return as output, in this case, is 在这种情况下,我想返回的结果是

1 9 1 9
2 7 2 7
3 3 3 3
4 -3 4 -3

To write this in really sketchy pseudocode, I want to do something like this: 要以非常粗略的伪代码编写此代码,我想执行以下操作:

awk '{print $1, $2 - `c_program $1`}' data_file awk'{print $ 1,$ 2-`c_program $ 1`}'data_file

But of course, I can't just pass $1, the awk variable, into a call to c_program. 但是当然,我不能只是将awk变量$ 1传递给对c_program的调用。 What's the right way to do this, and preferably, how could I do it while still maintaining the "awk one-liner"? 什么是正确的方法,最好是在保持“单线”的情况下如何做? (I don't want to pull out a sledgehammer and write a full-fledged C program to do this.) (我不想掏出一个大锤子来写一个成熟的C程序来做到这一点。)

你只是用awk做所有事情

awk '{cmd="c_program "$1; cmd|getline l;print $1,$2-l}' file

This shows how to execute a command in awk: 这显示了如何在awk中执行命令:

ls | awk '/^a/ {system("ls -ld " $1)}'

You could use a bash script instead: 您可以改用bash脚本:

while read line
do 
    FIRST=`echo $line | cut -d' ' -f1`
    SECOND=`echo $line | cut -d' ' -f2`
    OUT=`expr $SECOND \* 4`
    echo $FIRST $OUT `expr $OUT - $SECOND`
done

The shell is a better tool for this using a little used feature. 使用很少使用的功能,shell是一个更好的工具。 There is a shell variable IFS which is the Input Field Separator that sh uses to split command lines when parsing; 有一个外壳程序变量IFS ,它是输入字段分隔符,在解析时sh用来分隔命令行; it defaults to <Space><Tab><Newline> which is why ls foo is interpreted as two words. 它默认为<Space><Tab><Newline> ,这就是ls foo被解释为两个单词的原因。

When set is given arguments not beginning with - it sets the positional parameters of the shell to the contents of the arguments as split via IFS, thus: set是给定的参数与开始-它设置于壳的参数的内容的位置参数经由IFS,从而分裂:

#!/bin/sh
while read line ; do
    set $line
    subtrahend=`c_program $1`     
    echo $1 `expr $2 - $subtrahend`
done < data_file

Pure Bash, without using any external executables other than your program: 纯Bash,不使用程序以外的任何外部可执行文件:

#!/bin/bash
while read num1 num2
do
    (( result = $(c_program num2) - num1 ))
    echo "$num1 $result"
done

As others have pointed out: awk is not not well equipped for this job. 正如其他人指出的那样:awk不能胜任这项工作。 Here is a suggestion in bash: 这是bash的建议:

#!/bin/sh

data_file=$1

while read column_1 column_2 the_rest
do

    ((result=$(c_program $column_1)-$column_2))
    echo $column_1 $result "$the_rest"

done < $data_file

Save this to a file, say myscript.sh, then invoke it as: 将此保存到文件中,例如myscript.sh,然后按以下方式调用它:

sh myscript.sh data_file

The read command reads each line from the data file (which was redirected to the standard input) and assign the first 2 columns to $column_1 and $column_2 variables. read命令从数据文件中读取每一行(已重定向到标准输入),并将前两列分配给$ column_1和$ column_2变量。 The rest of the line, if there is any, is stored in $the_rest. 该行的其余部分(如果有的话)存储在$ the_rest中。

Next, I calculate the result based on your requirements and prints out the line based on your requirements. 接下来,我根据您的要求计算结果并根据您的要求打印行。 Note that I surround $the_rest with quotes to reserve spacing. 请注意,我用引号将$ the_rest括起来以保留间距。 Failure to do so will result in multiple spaces in the input file to be squeezed into one. 否则,将导致输入文件中的多个空格被压缩为一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM