增加块数据集中的特定列值并循环多次

问题描述 投票:0回答:5

我正在尝试按照上述顺序生成一个庞大的数据集。

4 0 1 642 643
4 642 643 1283 12
4 1283 1284 1924 1925
4 1924 1925 2565 2566
4 2565 2566 3206 3207
4 3206 3207 3847 3848
4 3847 3848 4488 4489
4 4488 4489 5129 5130

4 1 2 643 644
4 643 644 1284 1285
4 1284 1285 1925 1926
4 1925 1926 2566 2567
4 2566 2567 3207 3208
4 3207 3208 3848 3849
4 3848 3849 4489 4490
4 4489 4490 5130 5131

4 2 3 644 645
4 644 645 1285 1286
4 1285 1286 1926 1927
4 1926 1927 2567 2568
4 2567 2568 3208 3209
4 3208 3209 3849 3850
4 3849 3850 4490 4491
4 4490 4491 5131 5132

描述:有5列,第一列具有常量'4'。块中有8行(数据用空行分隔)。

现在,我的想法是将前一个块(从第1-8行开始)复制到第10-17行,并将第2-5列中的数字加1。此过程(现在第10-17行必须复制粘贴在第19-27行,第2列-5必须加1)必须迭代640次以生成我所需的集合。

谁能建议我如何生成这种类型的数据集?

awk sed vi
5个回答
1
投票
$ cat tst.awk
{
    for (fldNr=1; fldNr<=NF; fldNr++) {
        flds[NR,fldNr] = $fldNr
    }
}
END {
    maxRecs = 3
    for (recNr=1; recNr<=maxRecs; recNr++) {
        for (lineNr=1; lineNr<=NR; lineNr++) {
            printf "%s", flds[lineNr,1]
            for (fldNr=2; fldNr<=NF; fldNr++) {
                printf " %s", flds[lineNr,fldNr]+(recNr-1)
            }
            print ""
        }
        print ""
    }
}

.

$ cat file
4 0 1 642 643
4 642 643 1283 12
4 1283 1284 1924 1925
4 1924 1925 2565 2566
4 2565 2566 3206 3207
4 3206 3207 3847 3848
4 3847 3848 4488 4489
4 4488 4489 5129 5130

.

$ awk -f tst.awk file
4 0 1 642 643
4 642 643 1283 12
4 1283 1284 1924 1925
4 1924 1925 2565 2566
4 2565 2566 3206 3207
4 3206 3207 3847 3848
4 3847 3848 4488 4489
4 4488 4489 5129 5130

4 1 2 643 644
4 643 644 1284 13
4 1284 1285 1925 1926
4 1925 1926 2566 2567
4 2566 2567 3207 3208
4 3207 3208 3848 3849
4 3848 3849 4489 4490
4 4489 4490 5130 5131

4 2 3 644 645
4 644 645 1285 14
4 1285 1286 1926 1927
4 1926 1927 2567 2568
4 2567 2568 3208 3209
4 3208 3209 3849 3850
4 3849 3850 4490 4491
4 4490 4491 5131 5132

只需将maxRecs=3更改为maxRecs=640或您喜欢的任何值。


1
投票

这可能适合你(GNU sed&bash):

cat <<\!>file
4 0 1 642 643
4 642 643 1283 12
4 1283 1284 1924 1925
4 1924 1925 2565 2566
4 2565 2566 3206 3207
4 3206 3207 3847 3848
4 3847 3848 4488 4489
4 4488 4489 5129 5130

!

for n in {0..640}; do sed 's/\S\+/$((&+'$n'))/2g;s/.\+/printf "%d %d %d %d %d" &/e' file;done

回想起来,这也会起作用:

for n in {0..640}; do sed 's/\S\+/$((&+'$n'))/2g;s/.\+/echo "&"/e' file;done  

1
投票

使用Perl单线程

 perl -0777 -ne ' while( $i++<3) { s/(?!^)(\d+)/$1+1/gme; print "$_\n" } '

给定的输入

$ cat saideep.txt
4 0 1 642 643
4 642 643 1283 12
4 1283 1284 1924 1925
4 1924 1925 2565 2566
4 2565 2566 3206 3207
4 3206 3207 3847 3848
4 3847 3848 4488 4489
4 4488 4489 5129 5130

$ perl -0777 -ne ' while( $i++<3) { s/(?!^)(\d+)/$1+1/gme; print "$_\n" } ' saideep.txt
4 1 2 643 644
4 643 644 1284 13
4 1284 1285 1925 1926
4 1925 1926 2566 2567
4 2566 2567 3207 3208
4 3207 3208 3848 3849
4 3848 3849 4489 4490
4 4489 4490 5130 5131

4 2 3 644 645
4 644 645 1285 14
4 1285 1286 1926 1927
4 1926 1927 2567 2568
4 2567 2568 3208 3209
4 3208 3209 3849 3850
4 3849 3850 4490 4491
4 4490 4491 5131 5132

4 3 4 645 646
4 645 646 1286 15
4 1286 1287 1927 1928
4 1927 1928 2568 2569
4 2568 2569 3209 3210
4 3209 3210 3850 3851
4 3850 3851 4491 4492
4 4491 4492 5132 5133


$

0
投票

这些vi命令调用awk来执行任务:


:map z G{yGPG{!}awk '{for(i=NF;i>1;--i)++$i;print}'Ctrl+VCRCR1GOESC640izESC"add@a
  • :map z(...)CRCR定义了一个宏z
  • G{yGP复制文件的最后一段
  • qazxsw poi在最后一段执行awk 除了第一个,qazxsw poi增加所有字段 G{!}修改后的行
  • for(i=NF;i>1;--i)++$i;ESCprintESC准备640次调用z
  • 1GO运行准备好的命令

0
投票

以下bash脚本执行问题中提到的必需操作。

640iz

注意这里我将循环计数器变量'k'递增到639,因为我提供了第一组数据(最初的8行数据)。

© www.soinside.com 2019 - 2024. All rights reserved.