Bash 使用for循环打印多列的awk命令
我有一个单独的文件,其中包含第1列和第2列以及项目代码和名称,然后从第3列到第12列,其中包含其连续10天的消费量。 现在我需要把它转换成10个不同的文件。在每一列中,第1列和第2列应为相同的项目代码和项目名称,第3列将包含每一列中一天的消费量 输入文件:Bash 使用for循环打印多列的awk命令,bash,shell,awk,Bash,Shell,Awk,我有一个单独的文件,其中包含第1列和第2列以及项目代码和名称,然后从第3列到第12列,其中包含其连续10天的消费量。 现在我需要把它转换成10个不同的文件。在每一列中,第1列和第2列应为相同的项目代码和项目名称,第3列将包含每一列中一天的消费量 输入文件: Code | Name | Day1 | Day2 | Day3 |... 10001 | abcd | 5 | 1 | 9 |... 10002 | degg | 3 | 9 | 6 |... 10003 | gxyz
Code | Name | Day1 | Day2 | Day3 |...
10001 | abcd | 5 | 1 | 9 |...
10002 | degg | 3 | 9 | 6 |...
10003 | gxyz | 4 | 8 | 7 |...
我需要在不同的文件作为输出
文件1:
Code | Name | Day1
10001 | abcd | 5
10002 | degg | 3
10003 | gxyz | 4
文件2:
Code | Name | Day2
10001 | abcd | 1
10002 | degg | 9
10003 | gxyz | 8
文件3:
Code | Name | Day3
10001 | abcd | 9
10002 | degg | 6
10003 | gxyz | 7
等等
我写了这样的代码
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$3}' FILE_NAME > file1;
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$4}' FILE_NAME > file2;
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$5}' FILE_NAME > file3;
等等
现在我需要在“for”或“while”循环中写入它,这会更快
我不知道确切的密码,可能是这样的
for (( i=3; i<=NF; i++)) ; do awk 'BEGIN { FS = "\t" } ; {print $1,$2,$i}' input.tsv > $i.tsv; done
((i=3;i$i.tsv;完成)的
请帮助我获得我解释过的输出。bash+cut解决方案: 输入.tsv测试内容:
Code | Name | Day1 | Day2 | Day3
10001 | abcd | 5 | 1 | 9
10002 | degg | 3 | 9 | 6
10003 | gxyz | 4 | 8 | 7
day\u splitter.sh脚本:
#!/bin/bash
n=$(cat $1 | head -1 | awk -F'|' '{print NF}') # total number of fields
for ((i=3; i<=$n; i++))
do
fn="Day"$(($i-2)) # file name containing `Day` number
$(cut -d'|' -f1,2,$i $1 > $fn".txt")
done
结果:
bash day_splitter.sh input.tsv
$cat Day1.txt
Code | Name | Day1
10001 | abcd | 5
10002 | degg | 3
10003 | gxyz | 4
如果您确实需要在Bash中使用循环,则可以按如下方式修复循环:
for ((i = 3; i <= 10; i++)); do awk -v field=$i 'BEGIN { FS = "\t" } { print $1, $2, $field }' input.tsv > file$i.tsv; done
在纯awk中:
$ awk 'BEGIN{FS=OFS="|"}{for(i=3;i<=NF;i++) {f="file" (i-2); print $1,$2,$i >> f; close(f)}}' file
$awk'BEGIN{FS=OFS=“|”}{for(i=3;i>f;close(f)}}文件
解释:
$ awk '
BEGIN {
FS=OFS="|" } # set delimiters
{
for(i=3;i<=NF;i++) { # loop the consumption fields
f="file" (i-2) # create the filename
print $1,$2,$i >> f # append to target file
close(f) } # close the target file
}' file
$awk'
开始{
FS=OFS=“|”}#设置分隔符
{
对于(i=3;i>f#附加到目标文件
关闭(f)}#关闭目标文件
}"档案"
您正在混合使用shell和awk…单独使用awk..对不起,我不知道如何区分awk和shell。如果可能,请直接告诉我代码以获得输出。@Sundeep查看前面评论中doc链接的语法…您只需要将for循环移到awk中…给它一个tryHi Janos,您能给我您的邮件id吗?我想要o向你展示我最初的要求。@janosHi@ArunVenkitusamy,我宁愿不要。如果你的真正要求与你问题中的要求不同,那是非常不幸的,我希望你先写出来。问一些问题,得到一个答案,然后把问题改成其他问题是不公平的。如果某个小问题需要修改,请编辑您的问题,也许我们可以提供帮助。如果您需要不同的内容,最好问一个新问题。您好@janos,很抱歉浪费您的时间。我已经创建了一个新问题。请看一看[
awk -v FS='\t' '
NR == 1 {
for (i = 3; i < NF; i++) {
fn = "file" (i - 2) ".txt";
print $1, $2, $i > fn;
print "" >> fn;
}
}
NR > 2 {
for (i = 3; i < NF; i++) {
fn = "file" (i - 2) ".txt";
print $1, $2, $i >> fn;
}
}' inputfile
awk -v OFS=' | ' -v FS='[ |]+' '
$ awk 'BEGIN{FS=OFS="|"}{for(i=3;i<=NF;i++) {f="file" (i-2); print $1,$2,$i >> f; close(f)}}' file
$ awk '
BEGIN {
FS=OFS="|" } # set delimiters
{
for(i=3;i<=NF;i++) { # loop the consumption fields
f="file" (i-2) # create the filename
print $1,$2,$i >> f # append to target file
close(f) } # close the target file
}' file