Bash 在多个输入文件上使用awk

Bash 在多个输入文件上使用awk,bash,awk,gawk,Bash,Awk,Gawk,我一直在编写一个bash脚本,在这个脚本中,我一直在试图找出如何使用awk一次处理两个CSV文件,它将用于生成多个输出文件。简而言之,有一个主文件,它保存要发送到其他输出文件的内容,这些文件的名称和需要保存的记录数将从另一个文件派生。第一个n记录将进入第一个输出文件,随后n+1进入n+k进入第二个输出文件,依此类推 为了更清楚,这里有一个主记录文件的外观示例: x11,x21 x12,x22 x13,x23 x14,x24 x15,x25 x16,x26 x17,x27 x18,x28 x19,

我一直在编写一个
bash
脚本,在这个脚本中,我一直在试图找出如何使用
awk
一次处理两个CSV文件,它将用于生成多个输出文件。简而言之,有一个主文件,它保存要发送到其他输出文件的内容,这些文件的名称和需要保存的记录数将从另一个文件派生。第一个
n
记录将进入第一个输出文件,随后
n+1
进入
n+k
进入第二个输出文件,依此类推

为了更清楚,这里有一个主记录文件的外观示例:

x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29
以及其他文件的外观:

out_file_name_1,2
out_file_name_2,3
out_file_name_3,4
x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29
然后,名为
out\u file\u name\u 1的第一个输出文件应该如下所示:

out_file_name_1,2
out_file_name_2,3
out_file_name_3,4
x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29
然后,名为
out\u file\u name\u 2的第二个输出文件应该如下所示:

out_file_name_1,2
out_file_name_2,3
out_file_name_3,4
x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29
最后一个应该是这样的:

out_file_name_1,2
out_file_name_2,3
out_file_name_3,4
x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29

希望它足够清楚。

既然你问了,这里有一个awk的解决方案,但显然triplee的答案是更好的方法

$ cat oak.awk
BEGIN { FS = ","; fidx = 1 }

# Processing files.txt, init parallel arrays with filename and number of records
# to print to each one.
NR == FNR {
    file[NR] = $1
    records[NR] = $2
    next
}

# Processing main.txt. Print record to current file. Decrement number of records to print,
# advancing to the next file when number of records to print reaches 0
fidx in file && records[fidx] > 0 {
    print > file[fidx]
    if (! --records[fidx]) ++fidx
    next
}

# If we get here, either we ran out of files before reading all the records
# or a file was specified to contain zero records    
{ print "Error: Insufficient number of files or file with non-positive number of records"
  exit 1 }


$ cat files.txt
out_file_name_1,2
out_file_name_2,3
out_file_name_3,4

$ cat main.txt
x11,x21
x12,x22
x13,x23
x14,x24
x15,x25
x16,x26
x17,x27
x18,x28
x19,x29

$ awk -f oak.awk files.txt main.txt

$ cat out_file_name_1
x11,x21
x12,x22

$ cat out_file_name_2
x13,x23
x14,x24
x15,x25

$ cat out_file_name_3
x16,x26
x17,x27
x18,x28
x19,x29

我不会用Awk来做这个

while IFS=, read -u 3 filename lines; do
    head -n "$lines" >"$filename"
done 3<other.csv <main.csv

描述相当模糊。为了得到有用的答案,你可能需要把每件事都说清楚。例如:“有一个主文件保存一个内容的记录,该记录将被发送到一些其他输出文件,这些文件的名称和记录数将从另一个文件派生。”保存“内容记录”的格式是什么?究竟应该如何"调度"??这些名称和数字将如何“从另一个文件中派生”?为了获得最佳结果,请显示所有必需输入文件和生成的输出文件的小样本。。。。输出文件是什么样子的?这似乎是一个很好的方法,但是当我在OP的数据上运行它时,后两个输出文件是空的。对你来说有什么不同吗?是的,我在发帖前在这里测试过,现在再次验证;Bash4.1.5(1)-发行版(x86_64-pc-linux-gnu),Debian Squence。酷,我没想到你会在没有先验证的情况下发布。我用的是MacOSX,Bash3.2.57。我认为这可以归结为
(head-n2;head-n2)
只为我输出两行代码。你可以用
read
解决这个问题,但它有点笨重。我会给你一个建议。当然,这是可以做到的。是的,谢谢。事实上,这是我一直在寻找的答案,但由于@tripleee以优雅的方式回答了这个问题,我同意你继续他的答案。你没有关闭打开的文件句柄,因此当你拥有的文件超过一把时,你就会用完。一些Awk实现在这方面确实受到限制。这是我希望通过使用shell脚本来避免的一个问题;但是所有的事情都很重要,它不应该是这个脚本的主要补充(在移动到下一个文件时只需关闭旧文件)。