AWK, если число меньше предыдущего, как добавить предыдущее число к текущему числу и с этого момента

Из-за того, что не удалось правильно выполнить разделение сценария (, он запросил подтверждение, поскольку раздел был смонтирован, и, вопреки другим ответам, которые я нашел, не понял -1sили 100%), я только что нашел инструмент для расширения . ] который делает именно это.

Использование простое :growpart /dev/sda 3(, а затем resize2fs /dev/sda3или другая подходящая команда для используемого типа файловой системы ).

В Debian и Ubuntu он упакован как облако -гость -утилиты .

6
13.10.2019, 15:27
2 ответа

Вы должны были опубликовать несколько примеров строк и Ваш текущий сценарий, чтобы получить точный ответ.
Я бы не стал сравнивать, меньше ли число, но сохранил бы общее смещение при обработке строки после добавления смещения [0 для первого файла] и отрегулировал смещение.

Пример :awk 'FNR==1&&ARGIND>1{distoffset=distnow}{$2+=distoffset;distnow=$2+$3;print $0;}'

Предполагая, что у вас есть расстояние в поле 2 и длина текущей записи в поле 3 (это необходимо добавить к расстоянию предыдущей записи. Я предполагаю, что в противном случае первая запись файла имела то же расстояние, что и последняя запись предыдущего файла. файл.

По другому Вашему вопросу я не понимаю, чего Вы хотите. Добавление приращения 0,05 тоже не проблема, но не могу сказать Вам, как это сделать, если я не понимаю точного требования.


Таким образом, с дополнительной информацией с Вашей стороны я могу сделать свой пример более полным.
Сначала более подробная версия:

rm -f all.csv
awk '
FNR==1 {
 if (ARGIND>1) {
  timeoffset = timenow + 0.05;
  feetoffset = feetnow;
  metersoffset = metersnow;
  milesoffset = milesnow;
  kmeteroffset = kmeternow;
 } else {
  print $0;
 }
 next;
}
FNR>1{
 $1 += timeoffset; timenow = $1;
 $2 += feetoffset; feetnow = $2;
 $3 += metersoffset; metersnow = $3;
 $4 += milesoffset; milesnow = $4;
 $5 += kmeteroffset; kmeternow = $5;
 print $0;
}
' *.csv > all.csv

И еще один, использующий вместо этого циклы и массив:

rm -f all.csv
awk '
FNR==1 {
 if (ARGIND>1) {
  for (cfn = 1; cfn <= NF; cfn++) {
   offsetvals[cfn] = savedvals[cfn];
  }
  offsetvals[1] += 0.05;
 } else {
  print $0;
 }
 next;
}
FNR>1{
 for (cfn = 1; cfn <= NF; cfn++) {
  $cfn += offsetvals[cfn];
  savedvals[cfn] = $cfn;
 }
 print $0;
}
' *.csv > all.csv

И версия с циклом, которая является более общей и может повторно использоваться для файлов, где это не должно применяться ко всем полям или должно быть динамическим:

rm -f all.csv
awk '
BEGIN {
 procfields["tm"] = 1;
 procfields["ft"] = 2; procfields["mt"] = 3;
 procfields["ml"] = 4; procfields["km"] = 5; 
}
FNR==1 {
 if (ARGIND>1) {
  for (fnname in procfields) {
   cfn = procfields[fnname];
   offsetvals[cfn] = savedvals[cfn];
  };
  offsetvals[procfields["tm"]] += 0.05;
 } else {
  print $0;
 }
 next;
}
FNR>1{
 for (fnname in procfields) {
  cfn = procfields[fnname];
  $cfn += offsetvals[cfn];
  savedvals[cfn] = $cfn;
 };
 print $0;
}
' *.csv > all.csv

Предполагая, что строка заголовка, которую вы разместили, не содержится в файлах (, было бы легко реализовать, подумал ).
Второй предполагает, что все поля нуждаются в обработке.

Вы можете опустить все пробелы, включая символы новой строки из скрипта AWK, которые не находятся в кавычках (в этом случае пробелы вообще не заключаются в кавычки/необходимы ), как Вы предпочитаете. (Также можно опустить некоторые полу -коклоны, но я предпочитаю этого не делать.)

1
27.01.2020, 20:29

Вот решение на Python, на всякий случай:

import fileinput
from decimal import *

def main():
    save_values = [Decimal(0.0) for n in range(5)]
    last_values = save_values.copy()

    header_shown = False

    for line in fileinput.input():
        line = line.strip()
        if line == "":
            continue
        if line.startswith("Time"):
            if not header_shown:
                print(line)
                header_shown = True
            continue
        (time, feet, meters, miles, kms) = [Decimal(x) for x in line.split()]
        if time == 0.0:
            save_values = last_values.copy()
            continue
        time += save_values[0]
        feet += save_values[1]
        meters += save_values[2]
        miles += save_values[3]
        kms += save_values[4]
        print("{}\t{}\t{}\t{}\t{}".format(time, feet, meters, miles, kms))
        last_values = [time, feet, meters, miles, kms]

if __name__ == "__main__":
    main()

Это дает немного другой вывод, в вашем выводе у вас есть:

676.95  9727.547469   2964.956469   1.842339    2.964956
677     9727.547469   2964.956469   1.842339    2.964956

Но я думаю, что правильный вывод должен быть:

676.95  9727.547469 2964.956469 1.842339    2.964956
677.00  9728.234848 2965.165982 1.842469    2.965166
3
27.01.2020, 20:29

Теги

Похожие вопросы