【问题标题】:How to use AWK to continuously output lines from a file如何使用 AWK 从文件中连续输出行
【发布时间】:2020-09-15 04:58:16
【问题描述】:

我有一个多行的文件,我想连续输出文件的一些行,比如第一次,从第1行打印到第5行,下一次,从第2行打印到第6行,等等。 我发现 AWK 是一个非常有用的功能,我尝试自己编写代码,但它什么也没输出。 以下是我的代码

#!/bin/bash
for n in `seq 1 3`
do
  N1=$n
  N2=$((n+4))
  awk -v n1="$N1" -v n2="$N2" 'NR == n1, NR == n2 {print $0}' my_file >> new_file
done

例如,我有一个名为 my_file 的输入文件

1 99 tut
2 24 bcc
3 32 los
4 33 rts
5 642 pac
6 23 caas
7 231 cdos
8 1 caee
9 78 cdsa

然后我希望输出文件为

1 99 tut
2 24 bcc
3 32 los
4 33 rts
5 642 pac
2 24 bcc
3 32 los
4 33 rts
5 642 pac
6 23 caas
3 32 los
4 33 rts
5 642 pac
6 23 caas
7 231 cdos

【问题讨论】:

  • 感谢您以代码的形式展示您的努力。恕我直言,您可以在单个 awk 本身中执行此操作。您能否在此处发布您的输入和预期输出示例,以便更好地理解问题,我们也可以在单个 awk(如果可能)中执行此操作。
  • 嗨@RavinderSingh13 我只是编辑它,希望现在更清楚。谢谢。
  • 我试过你的代码,new_file 的输出看起来是正确的。
  • @Barmar 我换了另一台电脑,现在我的代码也可以工作了。感谢您的评论,它提醒我问题可能与系统有关。

标签: linux bash shell awk


【解决方案1】:

您能否尝试在 GNU awk 中使用所示示例进行跟踪、编写和测试。如果需要在lines_from 变量中提及所有需要打印的行,那么有一个名为till_lines 的变量告诉我们需要从特定行打印多少行(例如--> 从第一行打印接下来的4行也是)。另一方面,我已经测试了 OP 的代码,它对我来说运行良好,它使用 new_file 生成输出文件,因为在 bash 循环中调用 awk 不是好的做法,因此在这里也将其添加为改进。

awk -v lines_from="1,2,3" -v till_lines="4" '
BEGIN{
  num=split(lines_from,arr,",")
  for(i=1;i<=num;i++){ line[arr[i]] }
}
FNR==NR{
  value[FNR]=$0
  next
}
(FNR in line){
  print value[FNR] > "output_file"
  j=""
  while(++j<=till_lines){ print value[FNR+j] > "output_file" }
}
'  Input_file  Input_file

当我看到output_file 的内容时,我可以看到以下内容:

cat output_file
1 99 tut
2 24 bcc
3 32 los
4 33 rts
5 642 pac
2 24 bcc
3 32 los
4 33 rts
5 642 pac
6 23 caas
3 32 los
4 33 rts
5 642 pac
6 23 caas
7 231 cdos

说明:为上述添加详细说明。

awk -v lines_from="1,2,3" -v till_lines="4" '    ##Starting awk program from here and creating 2 variables lines_from and till_lines here, where lines_from will have all line numbers which one wants to print from. till_lines is the value till lines one has to print.
BEGIN{                                           ##Starting BEGIN section of this program from here.
  num=split(lines_from,arr,",")                  ##Splitting lines_from into arr with delimiter of , here.
  for(i=1;i<=num;i++){                           ##Running a for loop from i=1 to till value of num here.
    line[arr[i]]                                 ##Creating array line with index of value of array arr with index of i here.
  }
}
FNR==NR{                                         ##Checking condition FNR==NR which will be TRUE when 1st time Input_file is being read.
  value[FNR]=$0                                  ##Creating value with index as FNR and its value is current line.
  next                                           ##next will skip all further statements from here.
}
(FNR in line){                                   ##Checking condition if current line number is coming in array then do following.
  print value[FNR] > "output_file"               ##Printing value with index of FNR into output_file
  j=""                                           ##Nullifying value of j here.
  while(++j<=till_lines){                        ##Running while loop from j=1 to till value of till_lines here.
    print value[FNR+j] > "output_file"           ##Printing value of array value with index of FNR+j and print output into output_file
  }
}
'  Input_file Input_file                         ##Mentioning Input_file names here.

【讨论】:

  • @RavinderSingh13 感谢您的努力,我通过更换另一台计算机解决了我的问题,看来应该归咎于系统。您的脚本和 cmets 很有教育意义,谢谢。
  • @witt.S,欢迎您,恕我直言,我想在这里指出一点。老实说,您应该避免使用for 循环,然后在其中调用awk。在 for 循环的每次迭代中调用 awk 恕我直言,如果可能的话,您可以使用这个单一的解决方案欢呼。
【解决方案2】:

另一个awk变种

awk '
BEGIN {N1=1; N2=5}
arr[NR]=$0 {}
END {
    while (arr[N2]) {
        for (i=N1; i<=N2; i++)
            print arr[i] 
        N1++
        N2++
    }
}
' file

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多