awk,System()函数,与shell交互

时间:2016-03-24 17:56:32

标签: bash awk

我有一个list farm.txt:

cow
chicken
horse
pig

我有以下逗号分隔值的字符串,分配给BASH中的变量$ header:

animal,food_type,food_amount,feed_time

最后,我有一个文件care.csv,其中包含有关每种动物护理的数据:

cow,hay,2,12:00
cow,grain,3,12:00
chicken,corn,1000,11:00
pig,slop,76,04:00
horse,apple,1,23:00
...

我使用AWK获取farm.txt中的每个单词并使用它来创建格式为#34; [animal] _care.csv"的新.csv文件。

awk -F '\r' 'NR > 1 { system("touch " $1"_care.csv") }' farm.txt

此脚本可以解决此问题。我得到了我期望的输出:

cow_care.csv
chicken_care.csv
horse_care.csv
pig_care.csv

我现在要做的是再次使用awk循环通过care.csv,并将每一行分配给相应的[animal] _care.csv文件。这是我正在尝试的:

awk -F ',' '{ system("echo " $0 " >> " $1 "_stale.csv") }' care.csv

但这不起作用。最后,我想将字符串$ header放在每个[anima] _care.csv文件的开头。

我很难过,有人能指出我正确的方向吗?感谢。

2 个答案:

答案 0 :(得分:2)

您可以简单地redirect the output of print to a file

awk -F, '{file=$1"_stale.csv"; print $0 >> file; close(file)}' care.csv
此处不需要

system()。不要错过关闭文件,否则你可能会得到“太多打开文件描述符”,具体取决于care.csv中的行数。

如果您还要打印标题,请使用:

awk -F, 'NR==1{header=$0; next} # Save the header on the first line
     {file=$1"_stale.csv"; print header > file; print $0 >> file; close(file)}
' care.csv

这假定标题位于care.csv之上。如果要通过命令行传递标题,请使用:

awk -F, -v header="$header" \
  '{file=$1"_stale.csv"; print header > file; print $0 >> file; close(file)}' care.csv

答案 1 :(得分:2)

如果你想添加标题,假设文件按动物名称排序

$ awk -F, -v h="$header" 'p!=$1{print h > $1"_stale.csv"; p=$1}
                               {print > $1"_stale.csv"}' care.csv

$ tail *stale.csv

==> chicken_stale.csv <==
animal,food_type,food_amount,feed_time
chicken,corn,1000,11:00

==> cow_stale.csv <==
animal,food_type,food_amount,feed_time
cow,hay,2,12:00
cow,grain,3,12:00

==> horse_stale.csv <==
animal,food_type,food_amount,feed_time
horse,apple,1,23:00

==> pig_stale.csv <==
animal,food_type,food_amount,feed_time
pig,slop,76,04:00

如果文件未排序,只需将第一个块更改为

!($1 in a){print h > $1"_stale.csv"; a[$1]}