Bash 如何在循环中使用awk命令生成多个精简数据文件

Bash 如何在循环中使用awk命令生成多个精简数据文件,bash,loops,awk,Bash,Loops,Awk,我有几个8列120000行的大数据文件。现在我想从第100行开始,每200行保留一行。我将脚本文件thin.sh设置为: awk '(NR%200==100)' original_file > thinned_file 但是,现在我有30个原始文件,这意味着我必须一点一点地修改命令30次,原始文件的名称类似于: data.0000.dat, data.0001.dat data.0002.dat, ..., data.0029.dat 我认为必须有某种方法将awk命令嵌入到循环中以实现

我有几个8列120000行的大数据文件。现在我想从第100行开始,每200行保留一行。我将脚本文件thin.sh设置为:

awk '(NR%200==100)' original_file > thinned_file
但是,现在我有30个原始文件,这意味着我必须一点一点地修改命令30次,原始文件的名称类似于:

data.0000.dat, data.0001.dat data.0002.dat, ..., data.0029.dat
我认为必须有某种方法将
awk
命令嵌入到循环中以实现我的目标,可能类似于:

for(i=0;i<30;i++);
do
    awk '(NR%200==100)' data.$i.dat > data.$i_thinned.dat
done
用于(i=0;i数据.$i_thinded.dat
完成
但是我知道在文件名中,
$I
前面有两位
00
。我可以使用
sprintf(“%s”)
或其他什么吗?如果可以,如何安排
awk
sprinf
的顺序? 我使用ubuntu和bash。

和seq:

for i in $(seq -f %04g 1 29); do
  awk 'NR % 200 == 100' "data.${i}.dat" > "data.${i}_thinned.dat"
done
或者使用bash:

for i in {0001..0029}; do
在第一个代码段中,引号并不是绝对必要的,因为我们知道
$i
不包含任何邪恶的内容,但最好对shell脚本中的扩展持怀疑态度是必需的,因此shell不需要使用变量
$i_thinded
。它们在
“data.${i}.dat”
中不是绝对必需的,因为shell变量名中不能包含
,但一致性很好。

ingedints(GAWK) 1
FNR
-当前文件中的记录编号
1
match
-匹配正则表达式字符串,可以将组捕获到数组中。
1
print
-打印以下数据(如果未提供任何数据,则默认为当前记录)
1
*.dat
-当前控制器中以.dat结尾的所有文件


说明书
  • 在条件块中,检查当前文件中的当前记录编号除以200后是否剩余100
  • 如果确实如此,则运行下一个块
    {..}
  • 获取当前文件名并匹配到最后一个点,使用
    (.*)
    将在此之前的所有内容捕获到数组
    a
  • 使用捕获的日期
    a[1]
    和扩展名
    \u thinded.dat
  • 最后在末尾添加
    *.dat
    ,以读取当前目录中的所有.dat文件

  • 结果代码
    您只需要:

    awk 'FNR==1{close(out); out=FILENAME; sub(/\.dat/,"_thinned&",out)} (FNR%200==100){print > out}' data.[0-9][0-9][0-9][0-9].dat
    

    我使用
    data.[0-9][0-9][0-9][0-9].dat
    作为文件名全局模式,而不是
    data.*.dat
    以防您在之前生成所有“细化”文件的同一目录中重新运行脚本。

    只需将所有文件名放在
    awk
    之后,或者让shell为您执行
    awk'{…}“*.dat
    您可能必须将
    NR
    更改为
    FNR
    @EdMorton您不需要关闭它吗?@EdMorton啊,对了,所有版本的gawk都是这样吗?@EdMorton匹配在其他AWK上不起作用,所以我认为这不会是一个问题。当然,这比不需要
    关闭它的可能性要小。不过,我还是会添加它。”在这种情况下:)也可以告诉我一些文件,说awk处理所有文件关闭?我只能找到这个页面,我试过你的代码,但它似乎不工作。我的最终测试文件是
    data.0003.127.dat
    data.0006.127.dat
    data.0009.127.dat
    data.0012.127.dat
    ,因此我将代码更改为:{0003 0006 0009 0012}中I的
    ;完成awk'NR%200==100'数据。$i.127.dat>$i_thinked.dat完成
    。但是当我在终端中运行脚本时,它会说:
    awk:cannot open data.{.127.dat(没有这样的文件或目录)
    awk:cannot open data.0012.}.127.dat(没有这样的文件或目录)
    ,除上述两个文件外,
    0006
    0009
    也被减薄。括号用于0001和0029之间的扩展。如果您只想选择几个select标记,请在0003 0006 0009 0012中为i使用
    。运行
    echo{0001..0029}
    查看
    {..}
    的功能。如果您想要一个增量大于1的一般情况,
    seq
    可能是一种方法,如
    for i in$(seq-f%04g 3 3 12)
    我在
    .sh
    中更改了代码,正如我提到的“我将代码更改为:{0003 0006 0009 0012}”。你的意思是我需要拆下支架?啊,我试过了,但是脚本只生成了一个名为“127..dat”的文件,实际上我检查了里面的数据,应该是文件
    127.12_thinded.dat
    ,然后我在
    127.$I_thinded.dat
    中删除了
    127
    。这一次,没有生成精简的dat文件。哦,我知道。
    ${i}
    中的
    i
    周围应该有大括号——它正在寻找一个名为
    i\u thinded
    的变量。这就是我没有注意到的结果:P我将把它编辑到第一个循环中。
    awk 'FNR==1{close(out); out=FILENAME; sub(/\.dat/,"_thinned&",out)} (FNR%200==100){print > out}' data.[0-9][0-9][0-9][0-9].dat