在字段中循环并在awk中打印上一行

在字段中循环并在awk中打印上一行,awk,Awk,我一直在与awk斗争,以使这项工作,但我一直无法做到这一点。我有以下两行: = filename: /path/to/file years="1990,2001" 我需要每年根据给定值检查引号之间的距离,然后打印前一行(如果匹配),并获取文件名,结果只需要匹配找到的第一行。值和运算符,即=、、~将通过变量传递给awk,如: value="2000" string"=\$2 < $value" # just an exa

我一直在与awk斗争,以使这项工作,但我一直无法做到这一点。我有以下两行:

= filename: /path/to/file
years="1990,2001"
我需要每年根据给定值检查引号之间的距离,然后打印前一行(如果匹配),并获取文件名,结果只需要匹配找到的第一行。值和运算符,即=、、~将通过变量传递给awk,如:

value="2000"
string"=\$2 < $value"      # just an example

awk ... '"$string"' ...
输出匹配:

/mnt/project1/record2.txt
/mnt/project1/record4.txt

我还在学习AWK,但你想要类似的东西吗 下面是script.awk:

使用以下输入运行:

就像这样:

$ ./script.awk input
filename:  /path/to/file5

试着做一些超出你展示的假设。。。。 下面是一个如何解析它的示例

$: cat tst
= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/first
years="1990,0001"

= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/both
years="1990,2001"

= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/second
years="1790,2001"

= filename: /path/to/file/none
years="1890,1001"


$: awk '/filename:/ { fn=$3 } /years=/{ split($0,a,"[^0-9]+");
          for (y in a) { if (a[y]>1950) { printf "%s(%s)\n",fn,a[y]; break; } } }' tst
/path/to/file/first(1990)
/path/to/file/both(1990)
/path/to/file/second(2001)

如果你需要这些年的变量,你可以这样做

awk -v y0=1990 -v y1=2001 '
$0 ~ "^years=\"" y0 "," y1 "\"$" {
    printf("filename: %s\n", filename);
}

/^= filename/ {
    filename = $3
}
' file.txt
假设:


OP将始终搜索小于的日期。请将样本输入无描述、无图像、无链接和该样本输入的所需输出添加到您的问题中,无评论。您的示例显示年份<2000;您是否总是在寻找一个小于,=,date1的日期?否,它需要是任何运算符或~如果需要的话,也可以是字符串。“$2[operator][value]”将作为字符串传递给AWK:即var=\$2<$search\u值,然后是AWK…'$var'…@bcHelix这是一个与您的问题中当前显示的要求非常不同的要求,您可以从迄今为止收到的答案中看到这一点。请您的问题提供更清晰的需求说明和更真实的示例。您的示例代码显示了一个大于1950年的测试,但示例输入/输出基于一个小于2000年的测试;可能应该考虑更新问题,以便对你正在做的事情提供更简洁/清晰的解释;提供两个不同的例子不会有什么坏处,例如,>1950,@markp fuso:当然,OP在我发布我的答案后编辑了他们的问题……请查看何时/如何调用getline。@EdMorton:我的代码到底出了什么问题?请阅读那篇文章,它会告诉你的。我写这篇文章是为了不必反复讨论这些问题。这篇文章看起来很有效。这可以与字符串一起使用;i、 a[y]~一些字符串引用字符串-a[y]~一些字符串。
$ ./script.awk input
filename:  /path/to/file5
$: cat tst
= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/first
years="1990,0001"

= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/both
years="1990,2001"

= filename: /path/to/file/none
years="1890,1001"

= filename: /path/to/file/second
years="1790,2001"

= filename: /path/to/file/none
years="1890,1001"


$: awk '/filename:/ { fn=$3 } /years=/{ split($0,a,"[^0-9]+");
          for (y in a) { if (a[y]>1950) { printf "%s(%s)\n",fn,a[y]; break; } } }' tst
/path/to/file/first(1990)
/path/to/file/both(1990)
/path/to/file/second(2001)
awk -v y0=1990 -v y1=2001 '
$0 ~ "^years=\"" y0 "," y1 "\"$" {
    printf("filename: %s\n", filename);
}

/^= filename/ {
    filename = $3
}
' file.txt
$ cat file_year.dat
= filename: /mnt/project1/record1.txt
years="2005,2019,2011,2012,2013"             # no match

= filename: /mnt/project1/record2.txt
years="1996,2000"                            # match on 1996 < 2000

= filename: /mnt/project1/record3.txt
years="2005,2001,2012"                       # no match

= filename: /mnt/project1/record4.txt
years="2010,2009,1997,2000"                  # match on 1997 < 2000

= filename: /mnt/project1/record5.txt
years="2010,2009,2007,1947"                  # match on 1947 < 2000
awk -v tgt=2000 '                            # pass target date in as awk variable "tgt"
/^= filename: / { fn=$(NF)                   # save the filename in awk variable "fn"
                  next                       # skip to the next line of input
                }
fn != ""        { n=split($0,arr,"[,\"]")    # if "fn" is set then split the current line on double quotes
                                             # and commas; store results (ie, individual years)
                                             # in array "arr[]"
                  for (i=2; i<n; i++)        # process arr[2-(n-1)] elements (individual years)
                      if ( arr[i] < tgt )    # if less than "tgt" ...
                         { print fn          # print associated filename ("fn") and ...
                           break             # break out of loop
                         }
                   fn=""                     # clear "fn" varible
                }
' file_year.dat
/mnt/project1/record2.txt
/mnt/project1/record4.txt
/mnt/project1/record5.txt