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

直接在AWK中设置BASH环境变量(在AWK单行程序中),bash,shell,awk,Bash,Shell,Awk,我有一个文件,它有两列浮点值。我还有一个C程序,它接受一个浮点值作为输入,并返回另一个浮点值作为输出 我想做的是:对于原始文件中的每一行,使用第一列中的值作为输入执行C程序,然后打印出第一列(不变),第二列减去C程序的结果 例如,假设c_程序返回输入的平方,其行为如下: $c_计划4 16 $ 假设数据_文件如下所示: 110 2.11 3 12 4 13 在本例中,我想作为输出返回的是 19 27 3 4-3 要用非常粗略的伪代码编写此代码,我想做如下操作: awk'{print$1,$2-`

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

我想做的是:对于原始文件中的每一行,使用第一列中的值作为输入执行C程序,然后打印出第一列(不变),第二列减去C程序的结果

例如,假设c_程序返回输入的平方,其行为如下:

$c_计划4
16
$

假设数据_文件如下所示:

110
2.11
3 12
4 13

在本例中,我想作为输出返回的是

19
27
3
4-3

要用非常粗略的伪代码编写此代码,我想做如下操作:

awk'{print$1,$2-`c_program$1`}数据文件


但当然,我不能把$1,awk变量,传递给c_程序调用。做这件事的正确方法是什么?最好是,我如何在保持“awk一号班轮”的同时做到这一点?(我不想拿出一把大锤,编写一个完整的C程序来完成这项工作。)

这显示了如何在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

这显示了如何在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

使用很少使用的特性,shell是一个更好的工具。有一个shell变量
IFS
,它是sh在解析时用来拆分命令行的输入字段分隔符;它默认为
,这就是为什么
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
#/垃圾箱/垃圾箱
读行时;做
设置$line
subtrahand=`c_程序$1`
回显$1`expr$2-$subtrahand`
完成
使用很少使用的功能,shell是一个更好的工具。有一个shell变量
IFS
,它是sh在解析时用来拆分命令行的输入字段分隔符;它默认为
,这就是为什么
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
#/垃圾箱/垃圾箱
读行时;做
设置$line
subtrahand=`c_程序$1`
回显$1`expr$2-$subtrahand`
完成
您只需在awk中完成所有操作

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

你只是在awk里做每件事

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

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

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

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

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

正如其他人所指出的: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
read命令从数据文件(重定向到标准输入)中读取每一行,并将前两列分配给$column_1和$column_2变量。行的其余部分(如果有)存储在$The_rest中


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

正如其他人指出的那样: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
read命令从数据文件(重定向到标准输入)中读取每一行,并将前两列分配给$column_1和$column_2变量。行的其余部分(如果有)存储在$The_rest中


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

expr
不支持浮点值,请使用
bc
dc
awk
我建议改用
设置--$line
的习惯。
expr
不支持浮点值,请使用
bc
dc
awk
我建议改用
set--$line
的习惯。expr不支持浮点值,使用bc、dc或awkexpr不支持浮点值,使用bc、dc或awkAh,我不知道这个漂亮的bash功能。谢谢还有使用bash进行浮点pt计算的问题,尽管OP没有说他可能有浮点(小数)啊,我不知道bash的这个好特性。谢谢还有使用bash进行浮点pt计算的问题,尽管OP没有说他可能有非常优雅的浮点(小数);这正是我想要的。谢谢非常优雅;这正是我想要的。谢谢@Hai,“awk不适合这项工作。”。那是胡说八道。您还应该注意浮点计算。Bash在这方面失败了,但awk没有。@Hai,“awk没有做好这项工作的准备。”。那是胡说八道。您还应该注意浮点计算。Bash在这方面失败了,但awk没有。