在计算发送到 C 文件后使用 AWK 打印列
Using AWK to print a column after calculations sent to a C file
我的文本文件:
0000000022:tom:987:1,2:3,4
0000000223:jody:65:5,6:7,8
0000002224:ellie:43:9,8:7,6
0000022225:paul:21:5,4:3,2
0000222226:greg:0:1,2:3,4
我的终端命令:
$ ./script myFile.txt 2 3 4 5
我的代码:
#!/usr/bin/env bash
file=""
balance=$( awk -F'[:,]' '{ print $(NF-4) }' "$file" )
fee=$( awk -F'[:,]' '{ print $(NF-3), $(NF-2), $(NF-1), $(NF) }' "$file" | ./myProgram )
我怎样才能从余额中扣除费用,例如balanceAfter=$( balance - fee)
我正在使用 awk
浏览我的文件,然后我将文件中的字段和位置参数发送到 myProgram.c 以计算费用。然后我想打印文件中没有足够钱支付费用的人员的姓名。第三列是他们的余额。如果不清楚,请评论给我澄清。
对于这种情况,费用最终为 28,但会根据不同的参数和字段而改变,但在这种情况下,费用为 28,因此应该导致 Paul 和 Greg 的名字被推送到输出,因为他们资金不足
终端命令后我想要的输出:
$ ./script myFile 2 3 4 5
paul
greg
我的计算费用的.c程序是这样调用的:
$ echo 1 2 3 4 | ./myProgram 1 2 3 4
.c程序
// fee calculator
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv) {
// verify parameters just in case
if (argc != 5) {
return 0;
}
char *aStr = argv[1];
char *bStr = argv[2];
char *cStr = argv[3];
char *dStr = argv[4];
// Converts parameters to integers to use in calculations
int a = atoi(aStr);
int b = atoi(bStr);
int c = atoi(cStr);
int d = atoi(dStr);
int u1TapOn, v1TapOn, u2TapOff, v2TapOff;
int x1, y1, x2, y2;
int fare;
char strCoordinates[101];
char *ptr;
int coordinates[4];
while(fgets(strCoordinates, sizeof(strCoordinates), stdin) != NULL) {
char *s = strCoordinates;
for (int x = 0; x < 4; x++) {
coordinates[x] = strtol(s, &ptr, 10);
s = ptr;
}
u1TapOn = coordinates[0];
v1TapOn = coordinates[1];
u2TapOff = coordinates[2];
v2TapOff = coordinates[3];
//Calculates (x,y) for (u1, v1) Tap On Coordinates
x1 = (a * u1TapOn) + (b * v1TapOn);
y1 = (c * u1TapOn) + (d * v1TapOn);
//Calculates (x,y) for (u2, v2) Tap Off Coordinates
x2 = (a * u2TapOff) + (b * v2TapOff);
y2 = (c * u2TapOff) + (d * v2TapOff);
//Calculates the fare for each line of the input
fare = abs(x1 - x2) + abs(y1 - y2);
printf("%d\n", fare);
}
return 0;
}
计算的逻辑是,该文件代表一群人,他们拿着卡片,上面有钱。他们有有效的卡号、姓名、余额、坐标来计算行进距离以计算费用。
脚本应该查看谁的余额中没有足够的钱来支付费用,然后打印他们的名字。脚本应该带参数来调整费用值
我会尝试用 awk 给你一个关于这个特定案例的评论示例:(警告未经测试的代码)
#!/usr/bin/awk -f
BEGIN { FS =[:,] } # Set the Field Separator
{ #Do this for each line (no selector before the block)
"./myprogram" | getline fee[] # Get the fee value by calling the program with the 4 last fields from line and startan array of fee with username as key for later use
close("./myprogram") # To empty the buffer and avoid errors after
resultingbalance[]= - fee[] # some math to get the resulting balance for user, same into an array with user as key
}
END { # Important keyword, this code will run after the end of file has been reached
for (i in resultingbalance) { # loop over the array
if ((resultingbalance[i]) < 0) { # is the relusting balance negative ?
print i," can't pay its travel. Fee:",fee[i]," Balance at end:",resultingbalance[i] # if yes, print the key (username), the fee and the balance at end accessign the arrays
}
}
}
希望这会有所帮助
全部在 awk 中
awk -F[,:] -vx="2,3,4,5" '
{
split(x,a)
x1=(a[1]*)+(a[2]*)
y1=(a[3]*)+(a[4]*)
x2=(a[1]*)+(a[2]*)
y2=(a[3]*)+(a[4]*)
fare=(x1-x2)+(y1-y2)
fare<0&&fare*=-1}
fare>{print }
' test
如果你想使用你的 c 程序,使用 while 循环可能会更好
while read line;do
fare=$(awk -F[:,] '{===""}1' <<< "$line" | tester.c 2 3 4 5)
name=$(awk -F[:,] '{print }' <<< "$line" )
balance=$( awk -F[:,] '{ print }' <<< "$line")
((fare > balance)) && echo $name
done < test
输出
paul
greg
说明
Awk
-F[,:] -vx="2,3,4,5"
将字段 sep 设置为 ,
或 ;
。
将变量 x 设置为要在计算中使用的值。如果在 -vx=",,,"
等另一个脚本中,也可以将它们作为参数传递
split(x,a)
这会将传入 x 的参数拆分为数组 a
中的单独数组变量。它通过根据我们之前制作的字段分隔符拆分 x 来创建这些。
x1=(a[1]*)+(a[2]*)
...
fare=(x1-x2)+(y1-y2)
基于 c 程序逻辑的计算。
fare<0&&fare*=-1}
如果为负数,则转换为正数。
fare>{print }
如果 field 3
低于票价,则打印 field 2
中的姓名。
Loop
while read line;do
...
done < test
对于文件测试中的每一行
fare=$(awk -F[:,] '{===""}1' <<< "$line" | tester.c 2 3 4 5)
删除前 3 个字段,当字段更改时,(g)awk 会自动重新编译该行。默认的输出字段分隔符是 space,最后 4 个字段以正确的格式传送到 tester.c。
<<<
是一个 here 字符串,它将字符串传递给 awk,就好像它是一个 file/stdin。这样我们就可以把每一行分别传给awk了。
name=$(awk -F[:,] '{print }' <<< "$line" )
balance=$( awk -F[:,] '{ print }' <<< "$line")
设置其他变量的概念相同。
((fare > balance)) && echo $name
((...))
是允许执行数学方程和比较的 let
命令。
&&
像这样使用意味着不执行下一个命令,除非第一个 returns true
echo $name
不言自明。
需要更多信息请告诉我:)
资源
http://wiki.bash-hackers.org/commands/builtin/let(令((...))
)
https://www.gnu.org/software/gawk/manual/html_node/(awk 的东西)
http://tldp.org/LDP/abs/html/x17837.html(这里是字符串<<<
)
我的文本文件:
0000000022:tom:987:1,2:3,4
0000000223:jody:65:5,6:7,8
0000002224:ellie:43:9,8:7,6
0000022225:paul:21:5,4:3,2
0000222226:greg:0:1,2:3,4
我的终端命令:
$ ./script myFile.txt 2 3 4 5
我的代码:
#!/usr/bin/env bash
file=""
balance=$( awk -F'[:,]' '{ print $(NF-4) }' "$file" )
fee=$( awk -F'[:,]' '{ print $(NF-3), $(NF-2), $(NF-1), $(NF) }' "$file" | ./myProgram )
我怎样才能从余额中扣除费用,例如balanceAfter=$( balance - fee)
我正在使用 awk
浏览我的文件,然后我将文件中的字段和位置参数发送到 myProgram.c 以计算费用。然后我想打印文件中没有足够钱支付费用的人员的姓名。第三列是他们的余额。如果不清楚,请评论给我澄清。
对于这种情况,费用最终为 28,但会根据不同的参数和字段而改变,但在这种情况下,费用为 28,因此应该导致 Paul 和 Greg 的名字被推送到输出,因为他们资金不足
终端命令后我想要的输出:
$ ./script myFile 2 3 4 5
paul
greg
我的计算费用的.c程序是这样调用的:
$ echo 1 2 3 4 | ./myProgram 1 2 3 4
.c程序
// fee calculator
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv) {
// verify parameters just in case
if (argc != 5) {
return 0;
}
char *aStr = argv[1];
char *bStr = argv[2];
char *cStr = argv[3];
char *dStr = argv[4];
// Converts parameters to integers to use in calculations
int a = atoi(aStr);
int b = atoi(bStr);
int c = atoi(cStr);
int d = atoi(dStr);
int u1TapOn, v1TapOn, u2TapOff, v2TapOff;
int x1, y1, x2, y2;
int fare;
char strCoordinates[101];
char *ptr;
int coordinates[4];
while(fgets(strCoordinates, sizeof(strCoordinates), stdin) != NULL) {
char *s = strCoordinates;
for (int x = 0; x < 4; x++) {
coordinates[x] = strtol(s, &ptr, 10);
s = ptr;
}
u1TapOn = coordinates[0];
v1TapOn = coordinates[1];
u2TapOff = coordinates[2];
v2TapOff = coordinates[3];
//Calculates (x,y) for (u1, v1) Tap On Coordinates
x1 = (a * u1TapOn) + (b * v1TapOn);
y1 = (c * u1TapOn) + (d * v1TapOn);
//Calculates (x,y) for (u2, v2) Tap Off Coordinates
x2 = (a * u2TapOff) + (b * v2TapOff);
y2 = (c * u2TapOff) + (d * v2TapOff);
//Calculates the fare for each line of the input
fare = abs(x1 - x2) + abs(y1 - y2);
printf("%d\n", fare);
}
return 0;
}
计算的逻辑是,该文件代表一群人,他们拿着卡片,上面有钱。他们有有效的卡号、姓名、余额、坐标来计算行进距离以计算费用。
脚本应该查看谁的余额中没有足够的钱来支付费用,然后打印他们的名字。脚本应该带参数来调整费用值
我会尝试用 awk 给你一个关于这个特定案例的评论示例:(警告未经测试的代码)
#!/usr/bin/awk -f
BEGIN { FS =[:,] } # Set the Field Separator
{ #Do this for each line (no selector before the block)
"./myprogram" | getline fee[] # Get the fee value by calling the program with the 4 last fields from line and startan array of fee with username as key for later use
close("./myprogram") # To empty the buffer and avoid errors after
resultingbalance[]= - fee[] # some math to get the resulting balance for user, same into an array with user as key
}
END { # Important keyword, this code will run after the end of file has been reached
for (i in resultingbalance) { # loop over the array
if ((resultingbalance[i]) < 0) { # is the relusting balance negative ?
print i," can't pay its travel. Fee:",fee[i]," Balance at end:",resultingbalance[i] # if yes, print the key (username), the fee and the balance at end accessign the arrays
}
}
}
希望这会有所帮助
全部在 awk 中
awk -F[,:] -vx="2,3,4,5" '
{
split(x,a)
x1=(a[1]*)+(a[2]*)
y1=(a[3]*)+(a[4]*)
x2=(a[1]*)+(a[2]*)
y2=(a[3]*)+(a[4]*)
fare=(x1-x2)+(y1-y2)
fare<0&&fare*=-1}
fare>{print }
' test
如果你想使用你的 c 程序,使用 while 循环可能会更好
while read line;do
fare=$(awk -F[:,] '{===""}1' <<< "$line" | tester.c 2 3 4 5)
name=$(awk -F[:,] '{print }' <<< "$line" )
balance=$( awk -F[:,] '{ print }' <<< "$line")
((fare > balance)) && echo $name
done < test
输出
paul
greg
说明
Awk
-F[,:] -vx="2,3,4,5"
将字段 sep 设置为 ,
或 ;
。
将变量 x 设置为要在计算中使用的值。如果在 -vx=",,,"
split(x,a)
这会将传入 x 的参数拆分为数组 a
中的单独数组变量。它通过根据我们之前制作的字段分隔符拆分 x 来创建这些。
x1=(a[1]*)+(a[2]*)
...
fare=(x1-x2)+(y1-y2)
基于 c 程序逻辑的计算。
fare<0&&fare*=-1}
如果为负数,则转换为正数。
fare>{print }
如果 field 3
低于票价,则打印 field 2
中的姓名。
Loop
while read line;do
...
done < test
对于文件测试中的每一行
fare=$(awk -F[:,] '{===""}1' <<< "$line" | tester.c 2 3 4 5)
删除前 3 个字段,当字段更改时,(g)awk 会自动重新编译该行。默认的输出字段分隔符是 space,最后 4 个字段以正确的格式传送到 tester.c。
<<<
是一个 here 字符串,它将字符串传递给 awk,就好像它是一个 file/stdin。这样我们就可以把每一行分别传给awk了。
name=$(awk -F[:,] '{print }' <<< "$line" )
balance=$( awk -F[:,] '{ print }' <<< "$line")
设置其他变量的概念相同。
((fare > balance)) && echo $name
((...))
是允许执行数学方程和比较的 let
命令。
&&
像这样使用意味着不执行下一个命令,除非第一个 returns true
echo $name
不言自明。
需要更多信息请告诉我:)
资源
http://wiki.bash-hackers.org/commands/builtin/let(令((...))
)
https://www.gnu.org/software/gawk/manual/html_node/(awk 的东西)
http://tldp.org/LDP/abs/html/x17837.html(这里是字符串<<<
)