直接在 AWK 中设置 BASH 环境变量(在 AWK one-liner 中)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3107727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:14:56  来源:igfitidea点击:

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

bashshellawk

提问by Elliott

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
16
$

$ c_program 4
16
$

and suppose data_file looks like this:

并假设 data_file 看起来像这样:

1 10
2 11
3 12
4 13

1 10
2 11
3 12
4 13

What I'd like to return as output, in this case, is

在这种情况下,我想作为输出返回的是

1 9
2 7
3 3
4 -3

1 9
2 7
3 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`}' 数据文件

But of course, I can't just pass $1, the awk variable, into a call to 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.)

但当然,我不能只将 awk 变量 $1 传递到对 c_program 的调用中。这样做的正确方法是什么,最好是如何在保持“awk one-liner”的同时做到这一点?(我不想拿出大锤并编写一个成熟的 C 程序来做到这一点。)

回答by ghostdog74

you just do everything in awk

你只是用awk做所有事情

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

回答by Sjoerd

This shows how to execute a command in awk:

这显示了如何在 awk 中执行命令:

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

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

回答by msw

The shell is a better tool for this using a little used feature. There is a shell variable IFSwhich is the Input Field Separator that sh uses to split command lines when parsing; it defaults to <Space><Tab><Newline>which is why ls foois interpreted as two words.

shell 是一个更好的工具,它使用了一个很少使用的功能。有一个shell变量IFS,是sh在解析时用来分割命令行的Input Field Separator;它默认为<Space><Tab><Newline>which is whyls foo被解释为两个词。

When setis given arguments notbeginning with -it sets the positional parameters of the shell to the contents of the arguments as split via IFS, thus:

set给出的参数-它开头时,它会将 shell 的位置参数设置为通过 IFS 拆分的参数内容,因此:

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

回答by Paused until further notice.

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

回答by Hai Vu

As others have pointed out: awk is not not well equipped for this job. Here is a suggestion in bash:

正如其他人指出的那样:awk 并不适合这项工作。这是 bash 中的一个建议:

#!/bin/sh

data_file=

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. The rest of the line, if there is any, is stored in $the_rest.

read 命令从数据文件(已重定向到标准输入)中读取每一行,并将前 2 列分配给 $column_1 和 $column_2 变量。该行的其余部分(如果有)存储在 $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. Failure to do so will result in multiple spaces in the input file to be squeezed into one.

接下来,我根据您的要求计算结果并根据您的要求打印出该行。请注意,我用引号将 $the_rest 括起来以保留间距。如果不这样做,将导致输入文件中的多个空格被压缩为一个。