Увеличение определенного значения столбца в наборе блочных данных и повторение цикла несколько раз - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь создать огромный набор данных в указанном порядке.

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 на одну.Этот процесс (теперь строки 10-17 должны быть скопированы вставленными в строки 19-27, а столбцы 2-5 должны быть увеличены на 1) должен быть повторен около 640 раз, чтобы сгенерировать мой требуемый набор.

Может кто-нибудь предложить мне, как генерировать этот тип набора данных?

Ответы [ 5 ]

0 голосов
/ 25 февраля 2019

Использование Perl one-liner

 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 голосов
/ 24 февраля 2019
$ 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 или любое другое значение, которое вам нравится.

0 голосов
/ 24 февраля 2019

Следующий скрипт bash выполняет необходимые действия, как указано в вопросе.

#!/bin/bash
for k in {1..639}
do
 echo "$k th iteration"
 tail -8 MWE.txt > i
 awk '{print $1, $2+1, $3+1, $4+1, $5+1}' i > j
 cat j >> MWE.txt
done

Обратите внимание, здесь я увеличиваю переменную счетчика цикла 'k' до 639, поскольку я предоставляю первый набор данных (первые 8 строк)данных).

0 голосов
/ 24 февраля 2019

Это может работать для вас (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  
0 голосов
/ 23 февраля 2019

Эти vi команды вызывают awk для выполнения задачи:


:map z G{yGPG{!}awk '{for(i=NF;i>1;--i)++$i;print}' Ctrl + V CR CR 1GO ESC 640iz ESC "add@a
  • :map z (…) CR CR определяет макрос z
  • G{yGP дублирует последний абзац файла
  • G{!} выполняет awk в последнем абзаце
    • for(i=NF;i>1;--i)++$i; увеличивает все поля, кроме первого
    • print измененная строка
  • 1GO ESC 640izESC готовит 640 вызовов z
  • "add@a запускает подготовленные команды
...