Скрипт awk для печати информации в определенных строках - PullRequest
2 голосов
/ 13 декабря 2011

У меня есть несколько файлов данных, и мне нужно вытащить некоторую информацию.Я хотел бы использовать один сценарий awk для вывода данных, поэтому я могу высосать некоторые данные в массивы bash.

для этого, давайте предположим, что мне нужно следующее (1-индексированное): - Мне нужен awkчтобы напечатать первый столбец в строках 2, 3 и 4 - мне нужен awk для печати столбцов 1, 2 и 3 в строках 8 и более.но я хочу, чтобы все столбцы были напечатаны перед двумя столбцами, а два столбца перед тройками столбцов.

, используя следующий пример данных:

abc
def
ghi
jkl
mno
1a1
2b2
11 22 33 44
55 66 77 88
99 00 12 13
14 15 16 17

Я хотел бы, чтобы awk печаталстрока:

def ghi jkl 11 55 99 14 22 66 00 15 33 77 12 16

я создал следующее, которое, как я думал, будет работать, но я получаю сообщение об ошибке, в котором говорится, что «блоки END должны иметь часть действия».

awk '
BEGIN {i=0;}
{
   if ((NR >= 2) && (NR <= 4))
      print $1;
   if (NR >= 8)
   {
      col1_arr[i] = $1;
      col2_arr[i] = $2;
      col3_arr[i] = $3;
      i++;
   }
}
END
{
   for (j = 0; j < i; j++)
       print col1_arr[j];
   for (j = 0; j < i; j++)
       print col2_arr[j];
   for (j = 0; j < i; j++)
       print col3_arr[j];
}' /path/to/my/file

спасибовпереди времени.

Ответы [ 4 ]

2 голосов
/ 13 декабря 2011

Слегка многословно.Но это прекрасно, это делает его ремонтопригодным, если вы хотите сохранить его.

Каждое правило awk:

<Match> <Action>

Любой может быть пустым:

Пусто означает соответствие каждой строке.
Пусто означает печать (которая печатает текущую строку).

Конечно, END не имеет строки, поэтому печать теряет смысл.

То, что у вас есть:

END  -- No Action --
--No Match -- { print your col arrays }

Что вам нужно сделать, этопоместите действие в ту же строку, что и конец.

END {
for (j = 0; j < i; j++)
   print col1_arr[j];
for (j = 0; j < i; j++)
   print col2_arr[j];
for (j = 0; j < i; j++)
   print col3_arr[j];
}

Другая проблема, с которой вы столкнулись, заключается в том, что print помещает новую строку в строку, которую печатает.
, чтобы обойти это использование printf("<format string>", variables);

BEGIN {i=0;}
{
    if ((NR >= 2) && (NR <= 4))
        printf("%s ", $1);
    if (NR >= 8)
    {
        col1_arr[i] = $1;
        col2_arr[i] = $2;
        col3_arr[i] = $3;
        i++;
    }
}
END {
    for (j = 0; j < i; j++)
        printf("%d ", col1_arr[j]);
    for (j = 0; j < i; j++)
        printf("%d ", col2_arr[j]);
    for (j = 0; j < i; j++)
        printf("%d ", col3_arr[j]);
}
2 голосов
/ 13 декабря 2011

Это должно работать -

awk '
BEGIN{i=0;}
NR>=2 && NR<=4 {printf $1" "} 
NR >=8 {col1[i]=$1;col2[i]=$2;col3[i]=$3;i++;} 
END{for (i=0;i<=NR-8;i++) printf col1[i]" "; for(i=0;i<=NR-8;i++) printf col2[i]" ";for (i=0;i<=NR-8;i++) printf col3[i]" "}' INPUT_FILE


[jaypal:~/Temp] cat data
abc
def
ghi
jkl
mno
1a1
2b2
11 22 33 44
55 66 77 88
99 00 12 13
14 15 16 17

[jaypal:~/Temp] awk '
BEGIN{i=0;}
NR>=2 && NR<=4 {printf $1" "} 
NR >=8 {col1[i]=$1;col2[i]=$2;col3[i]=$3;i++;} 
END{for (i=0;i<=NR-8;i++) printf col1[i]" "; for(i=0;i<=NR-8;i++) printf col2[i]" ";for (i=0;i<=NR-8;i++) printf col3[i]" "}' data
def ghi jkl 11 55 99 14 22 66 00 15 33 77 12 16
1 голос
/ 13 декабря 2011

строка awk ниже должна сделать работу за вас:

awk '(NR==1 || NR>=5 && NR<=7){next;} 
{printf $1" ";if(NR>=8){two[NR]=$2;three[NR]=$3}}
END{for(x in two)printf two[x]" ";for(x in three) printf three[x]" "}' yourFile

тест на вашем примере:

kent$  echo "abc
def
ghi
jkl
mno
1a1
2b2
11 22 33 44
55 66 77 88
99 00 12 13
14 15 16 17 "|
awk '(NR==1 || NR>=5 && NR<=7){next;} 
{printf $1" ";if(NR>=8){two[NR]=$2;three[NR]=$3}}
END{for(x in two)printf two[x]" ";for(x in three) printf three[x]" "}'

выход

def ghi jkl 11 55 99 14 22 66 00 15 33 77 12 16 
0 голосов
/ 13 декабря 2011
awk 'END {
  printf "%s", (r OFS)
  for (i = 0; ++i <= l;)
    printf "%s", (m[i] (i < l ? OFS : RS))
  }
NR > 1 && NR < 5 {
  r = r ? r OFS $0 : $0
  }
NR >= 8 {
  for (i = 0; ++i <= l;)
    m[i] = i in m ? m[i] OFS $i : $i
  }' l=3 infile  
...