【问题标题】:Print line if column 2 is greater than column 2 on the next line如果第 2 列大于下一行的第 2 列,则打印行
【发布时间】:2019-09-03 02:50:37
【问题描述】:

我有一个包含多行的文件,这些行在第二列中都有一个日期。如果日期大于下一行的日期,我正在寻找一个打印整行的命令。
当不再是这种情况时,我希望它停止,不要打印任何其他内容。

我是菜鸟,所以如果你能解释你的答案,那就太好了。

我正在尝试使用 awk(答案可以是任何命令)

awk '$2 > ?nextline?$2 {print}' file

我找不到如何检查下一行或如何在第一次大于命令不正确后停止。

输入:

Jan 20 text1  
Jan 15 text2  
Jan 15 text3  
Jan 3 text4  
Jan 27 text5  
Jan 17 text6  
(more lines...) 

想要的输出:

Jan 20 text1  
Jan 15 text2  
Jan 15 text3  
Jan 3 text4

【问题讨论】:

  • 当这条线的 3 小于 Jan 27 text527 时,我不知道你的输出中的线 Jan 3 text4 是怎样的?你能详细说明一下吗?
  • (第 2 栏日期)20>15>3>27>17。 27 不小于 3。所以我想要从第一行到日期从 3 到 27 的所有内容。当以下行的日期较大时,我不想要该输出或之后的任何内容。
  • 就像在生活中一样,在软件中,根据已经发生的事情来做事情比根据将来会发生的事情来做事情要容易得多。所以不要根据下一行的内容来写需求,根据上一行的内容来写需求,你会发现想出解决方案会容易得多。

标签: bash shell awk sed


【解决方案1】:

awk 版本:

awk 'f && $2>f {exit} 1; {f=$2}' file
Jan 20 text1
Jan 15 text2
Jan 15 text3
Jan 3 text4
  • f && $2>f {exit} 测试是否设置了f 并且第二个字段大于f?是的,退出程序。
  • 1; 始终为真,因此请打印该行。
  • {f=$2}f 设置为第二个字段。

Cold 甚至可以缩短一些:

awk 'f&&$2>f{exit}f=$2' file
  • f=$2 通过将其设置为模式,它将为真并同时打印 f 设置为 $2
  • 如果存在,则此版本将跳过数据之间的打印空白行,否则。

【讨论】:

    【解决方案2】:

    通常,您必须颠倒您的要求。如果下一行做了某事,而不是打印出当前行,因为sed,awk等,看不到未来,如果当前行与上一行相比,你需要停止打印,因为awk和朋友可以通过将其存储在变量中来查看过去。

    既然你说语言无关紧要,那么一个简单的方法就是这样做:

    perl -palE 'BEGIN {$h = 999} last if $F[1] > $h; $h = $F[1]' < file
    

    我们在这里所做的是在-p“循环输入并在循环结束时打印行”中传递perl,-a“将空格上的行自动拆分到@F变量中”,@ 987654325@ "自动处理行尾"(这里不是严格要求,但只是大部分时间的一个好习惯)和-E "使用当前版本执行下一个参数的代码perl 指定”(-e 在这里就足够了,但同样是习惯)。我们传入的代码首先将$h(此时允许的最高值)设置为超出范围的值,我假设没有数字会是999+,因为你说它们是一个月中的几天,使用@987654329 @ 如果当前日期高于允许的最高值,则终止循环,如果我们超过 if,则将该高点设置为当前值。 Perl 现在会自动打印出当前行并循环到下一行。

    关键是我们只查看当前行并在变量中跟踪相关历史记录,这样我们就不需要查看未来。

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 2014-04-08
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      • 2018-05-23
      相关资源
      最近更新 更多