我非常感谢你的帮助,可能很简单.
我有一个表(table2.txt),它有一列随机生成的数字,大约有一百万行.
2655087
3721239
5728533
9082076
2016819
8983893
9446748
6607974
Run Code Online (Sandbox Code Playgroud)
我想创建一个重复10,000次的循环,这样对于迭代1,我将第1行到第4行打印到文件(file0.txt),对于迭代2,我打印第5到8行(file1.txt),等等上.
到目前为止我所拥有的是:
#!/bin/bash
for i in {0..10000}
do
awk 'NR==((4 * "$i") +1)' table2.txt > file"$i".txt
awk 'NR==((4 * "$i") +2)' table2.txt >> file"$i".txt
awk 'NR==((4 * "$i") +3)' table2.txt >> file"$i".txt
awk 'NR==((4 * "$i") +4)' table2.txt >> file"$i".txt
done
Run Code Online (Sandbox Code Playgroud)
file0.txt的所需输出:
2655087
3721239
5728533
9082076
Run Code Online (Sandbox Code Playgroud)
file1.txt的所需输出:
2016819
8983893
9446748
6607974
Run Code Online (Sandbox Code Playgroud)
这有什么问题,因为我从我的所有文件获得相同的输出(即它们看起来都像file0.txt的所需输出).希望您可以从我的脚本中看到,在第二次迭代期间,即当i = 2时,我希望输出为行5,6,7和8的值.
这可能是一个非常简单的语法错误,如果你能告诉我哪里出错了(或者给我一个不那么麻烦的解决方案,我将不胜感激!)
非常感谢你.
美丽的awk是你可以在awk一行中做到这一点:
awk '{ print > ("file"c".txt") }
(NR % 4 == 0) { ++c }
(c == 10001) { exit }' <file>
Run Code Online (Sandbox Code Playgroud)
这可以稍微优化一下,文件处理友好(cfr.James Brown):
awk 'BEGIN{f="file0.txt" }
{ print > f }
(NR % 4 == 0) { close(f); f="file"++c".txt" }
(c == 10001) { exit }' <file>
Run Code Online (Sandbox Code Playgroud)
为什么你的脚本失败了?
您的脚本失败的原因是您使用单引号并尝试将shell变量传递给它.你的行应该是:
awk 'NR==((4 * '$i') +1)' table2.txt > file"$i".txt
Run Code Online (Sandbox Code Playgroud)
但这非常难看,应该改进
awk -v i=$i 'NR==(4*i+1)' table2.txt > file"$i".txt
Run Code Online (Sandbox Code Playgroud)
为什么你的脚本慢?
处理文件的方式是循环10001次迭代.每次迭代,您执行4次awk调用.每次awk调用都会完整地读取完整文件并写出一行.所以最后你读了40004次你的文件.
要逐步优化脚本,我会执行以下操作:
awk打印行后终止步骤读取文件
#!/bin/bash
for i in {0..10000}; do
awk -v i=$i 'NR==(4*i+1){print; exit}' table2.txt > file"$i".txt
awk -v i=$i 'NR==(4*i+2){print; exit}' table2.txt >> file"$i".txt
awk -v i=$i 'NR==(4*i+3){print; exit}' table2.txt >> file"$i".txt
awk -v i=$i 'NR==(4*i+4){print; exit}' table2.txt >> file"$i".txt
done
Run Code Online (Sandbox Code Playgroud)将4个awk调用合并为一个.这可以防止每个循环周期反复读取第一行.
#!/bin/bash
for i in {0..10000}; do
awk -v i=$i '(NR<=4*i) {next} # skip line
(NR> 4*(i+1)}{exit} # exit awk
1' table2.txt > file"$i".txt # print line
done
Run Code Online (Sandbox Code Playgroud)删除最后一个循环(参见本答案的顶部)