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

时间:2010-06-24 06:41:54

标签: bash shell awk

我有一个包含两列浮点值的文件。我还有一个C程序,它将浮点值作为输入,并返回另一个浮点值作为输出。

我想要做的是:对于原始中的每一行,执行C程序,将第一列中的值作为输入,然后打印出第一列(未更改),然后打印第二列减去C程序的结果。

例如,假设c_program返回输入的平方并且行为如下:

$ c_program 4
16个
$

并假设data_file如下所示:

1 10
2 11
3 12
4 13

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

1 9
2 7
3 3
4 -3

要用非常粗略的伪代码写这个,我想做这样的事情:

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

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

5 个答案:

答案 0 :(得分:4)

你只是在awk中做所有事情

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

答案 1 :(得分:2)

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

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

您可以使用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

答案 2 :(得分:1)

使用一点点使用的功能,shell是一个更好的工具。有一个shell变量IFS,它是输入字段分隔符,用于在解析时分割命令行;它默认为<Space><Tab><Newline>,这就是ls foo被解释为两个单词的原因。

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

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

答案 3 :(得分:0)

Pure Bash,不使用程序以外的任何外部可执行文件:

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

答案 4 :(得分:0)

正如其他人所指出的那样:awk并没有为这份工作做好准备。以下是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

将其保存到文件中,例如myscript.sh,然后将其调用为:

sh myscript.sh data_file

read命令读取数据文件中的每一行(重定向到标准输入),并将前两列分配给$ column_1和$ column_2变量。该行的其余部分(如果有的话)存储在$ the_rest。

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