AWK распечатать FNR с шагом 0 - PullRequest
1 голос
/ 01 февраля 2012

Это скрипт, который я пытаюсь добавить к аргументу последнего аргумента, который печатает FNR в четвертое поле.

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
            }

Вот как выглядит вывод этого скрипта:

48.34   -55.88  19.19
26.95   24.36   13.43
25.53   4.45    -20.68
71.27   6.68    24.28
...

Это мой второй скрипт:

#!/usr/bin/awk -f

{ OFS = "\t"; $4="(Untitled "FNR-1")"; print $0 }

Передача первого скрипта во второй скрипт возвращает ожидаемый результат с FNR, начинающимся с 0 в четвертом поле.

48.34   -55.88  19.19   (Untitled 0)
26.95   24.36   13.43   (Untitled 1)
25.53   4.45    -20.68  (Untitled 2)
71.27   6.68    24.28   (Untitled 3)
...

Я попытался объединить сценарии, но я не получил вывод, который пытаюсь получить.

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
                        }

    { 
        OFS = "\t"
        $4="(Untitled "FNR-1")"
        print $4 
    }

Это вывод данных.Проблема в том, что он ссылается на тот же файл, а не на вывод из последней команды.

(Untitled 0)
(Untitled 1)
(Untitled 2)
(Untitled 3)
(Untitled 4)
(Untitled 5)
(Untitled 6)
(Untitled 7)
(Untitled 8)
(Untitled 9)
(Untitled 10)
(Untitled 11)
(Untitled 13)
(Untitled 14)
(Untitled 15)
48.34   -55.88  19.19
(Untitled 17)
26.95   24.36   13.43
(Untitled 18)
25.53   4.45    -20.68
(Untitled 19)
71.27   6.68    24.28
(Untitled 20)
...

Я также пробовал это:

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j

        OFS = "\t"
        $4="(Untitled "FNR-1")"
        print s OFS $4 
            }

Вывод ближе, но проблемаявляется то, что он по-прежнему рассчитывает от FNR этого аргумента.Мне нужно, чтобы он начинался с 0.

48.34   -55.88  19.19   (Untitled 17)
26.95   24.36   13.43   (Untitled 18)
25.53   4.45    -20.68  (Untitled 19)
71.27   6.68    24.28   (Untitled 20)
...

Может ли кто-нибудь показать мне правильный способ объединения этих сценариев?

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

Просто используйте инкрементную переменную вместо номера записи:

print s, "(Untitled " count++ ")"

Вы должны определить OFS в блоке BEGIN вместо переопределения его для каждой строки.

Вместо того, чтобы делать { sub(/\r$/,"") }, почему бы вам сначала не использовать "dos2unix" в вашем файле?

1 голос
/ 01 февраля 2012

Ваш первый скрипт печатается только тогда, когда встречается /^BEGIN_DATA$/,/^END_DATA$/.

Ваш объединенный скрипт выполняет print s при выполнении вышеуказанного условия, И выполняет print $4 для каждой строки, независимо от того, выполняется ли условие.

Как указал Гленн Джекман, проблема в том, что FNR - это «количество записей». Когда вы переходите от одного сценария к другому, второй сценарий получает выходные данные только первого, поэтому каждая строка вывода является новой записью для второго сценария.

Вам нужен счетчик, отличный от FNR.

BEGIN {
  count=0;
}

...

/^BEGIN_DATA$/,/^END_DATA$/ {
  s="";
  if (NF<2) {
    next;
  } else {
    for (j in a) [
            s=s?s"\t"$j:$j;
    }
    printf("%s\t(Untitled %d)", s, count++);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...