awk 脚本在特定行打印信息

发布于 2024-12-21 03:38:17 字数 897 浏览 2 评论 0原文

我有一些数据文件,我需要提取一些信息。我想使用一个 awk 脚本来获取数据,这样我就可以将一些数据吸入 bash 数组中。

为此,我们假设我需要以下内容(1 索引): - 我需要 awk 打印第一列的第 2、3 和 4 行 - 我需要 awk 在第 8 行及以上打印第 1、2 和 3 列。但我希望所有的列在第二列之前打印,第二列在第三列之前打印。

使用以下数据示例:

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 bocks 必须有一个操作部分”。

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

提前致谢。

i have some data files, and i need to pull some info out. i'd like to use a single awk script to get data out, so i can suck some data into bash arrays.

for this, let's assume i need the following (1-indexed):
- i need awk to print column one on lines 2, 3, and 4
- i need awk to print columns 1, 2, and 3 on lines 8 and over. but i want all of the column ones printed before the column twos, and the column twos before the column threes.

using the following data example:

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

i would want awk to print the string:

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

i created the following, which i thought would work, but i am getting an error saying "END bocks must have an action part".

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

thanks ahead of time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

土豪我们做朋友吧 2024-12-28 03:38:17

这应该有效 -

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

This should work -

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
眼波传意 2024-12-28 03:38:17

有点冗长。但这很好,如果你想保留它,它就可以维护。

每个 awk 规则是:

<Match> <Action>

任一可以为空:

Empty或 Empty表示匹配每一行。
空<动作>表示打印(打印当前行)。

当然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("", 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]);
}

Slightly verbose. But that's fine it makes it maintainable if you want to keep it.

Each awk rule is:

<Match> <Action>

Either may be empty:

Empty <Match> means match every line.
Empty <Action> means print (which prints the current line).

Of course END has no line so print becomes meaningless.

What you have is:

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

What you need to do is put the action on the same line as the end.

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];
}

The other problem you are having is that print puts a newline onto the string it prints.
to get around this use 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]);
}
云归处 2024-12-28 03:38:17

下面的 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 

the awk line below should do the job for you:

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

test with your example:

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]" "}'

output

def ghi jkl 11 55 99 14 22 66 00 15 33 77 12 16 
伏妖词 2024-12-28 03:38:17
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  
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  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文