Bash 使用for循环打印多列的awk命令

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

我有一个单独的文件,其中包含第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 | 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