awk 根据 if else 条件获取数据

awk get the data based on if else condition

我再次需要你的专业知识,我正在尝试使用 awk 做一些有条件的操作来获取列。

如果我查看 </code> 数据可以有 <code>year 并且在某些地方 date.

所以当 year 存在时打印很好,但是我有 date and time 的其他值,比如 05:17:27 然后我需要打印最后一个字段。

2021
2021
05:17:27
20:33:17
05:17:20
2020
2020
2021
2020
2021

下面是我的示例数据。

data_file.

yogutdb01   Mon 28 Jun 2021 11:19:56 PM MST
yogutdb02   Thu 30 Sep 2021 02:02:53 AM MST
yogutdb03   Thu Jul 13 05:17:27 2017
yogutdb04   Fri Jun 23 20:33:17 2017
yogutdb05   Thu Jul 13 05:17:20 2017
yogutdb06   Wed 24 Jun 2020 03:49:16 PM MST
yogutdb07   Wed 24 Jun 2020 04:05:10 PM MST
yogutdb08   Sat 22 May 2021 04:19:14 AM MST
yogutdb09   Thu 09 Apr 2020 12:16:32 PM CEST
yogutdb10   Tue 11 May 2021 03:03:02 PM MST

我的试用:我在下面使用,但在 else 条件下出现语法错误。

$ awk '{ (=="[^0-9]+$")print ,,,,; else print  ,,,,$NF}' my_data.text

期望应该是:

yogutdb01   2021 
yogutdb02   2021
yogutdb03   2017
yogutdb04   2017    
yogutdb05   2017
yogutdb06   2020
yogutdb07   2020
yogutdb08   2021
yogutdb09   2020
yogutdb10   2021

yogutdb01   Mon 28 Jun 2021
yogutdb02   Thu 30 Sep 2021
yogutdb03   Thu Jul 13 2017
yogutdb04   Fri Jun 23 2017
yogutdb05   Thu Jul 13 2017
yogutdb06   Wed 24 Jun 2020 
yogutdb07   Wed 24 Jun 2020 
yogutdb08   Sat 22 May 2021 
yogutdb09   Thu 09 Apr 2020 
yogutdb10   Tue 11 May 2021 
  • 您不能使用 == 运算符来测试正则表达式匹配。相反,您可以使用 match() 函数或 ~ 运算符。
  • 您应该将 ^ 正则表达式放在 [0-9] 前面,而不是里面。

那你试试看:

awk '{if (match(,/^[0-9]+$/)) print , , , , ; else print , , , , $NF}' my_data.text

输出:

yogutdb01 Mon 28 Jun 2021
yogutdb02 Thu 30 Sep 2021
yogutdb03 Thu Jul 13 2017
yogutdb04 Fri Jun 23 2017
yogutdb05 Thu Jul 13 2017
yogutdb06 Wed 24 Jun 2020
yogutdb07 Wed 24 Jun 2020
yogutdb08 Sat 22 May 2021
yogutdb09 Thu 09 Apr 2020
yogutdb10 Tue 11 May 2021

这是使用 ~ 运算符的替代方法:

awk ' ~ /^[0-9]+$/ {print , , , , ; next} {print , , , , $NF}' my_data.text

根据您想要的结果,您应该尝试以下可行的方法。

您可以使用 ~.

等正则表达式匹配
$ awk '{ if ( !~ /:/) { print ,,,,; next } { print ,,,, $NF } }'   exampl_data1

结果:

yogutdb01 Mon 28 Jun 2021
yogutdb02 Thu 30 Sep 2021
yogutdb03 Thu Jul 13 2017
yogutdb04 Fri Jun 23 2017
yogutdb05 Thu Jul 13 2017
yogutdb06 Wed 24 Jun 2020
yogutdb07 Wed 24 Jun 2020
yogutdb08 Sat 22 May 2021
yogutdb09 Thu 09 Apr 2020
yogutdb10 Tue 11 May 2021

顺便提一下,正如@tshiono 在评论中也提出的那样,要按顺序获得输出,您可以使用下面的方法。

$ awk '{ if ( !~ /:/) { print , , , , ; next } { print , , , , $NF } }'   exampl_data1

您可以打印前 4 个字段,并检查第 5 个字段是否只有 4 位数字。如果不止4位,打印最后一个字段。

awk '{print , , , , ( ~ /^[0-9]+$/ ?  : $NF)}' my_data.text

输出

yogutdb01 Mon 28 Jun 2021
yogutdb02 Thu 30 Sep 2021
yogutdb03 Thu Jul 13 2017
yogutdb04 Fri Jun 23 2017
yogutdb05 Thu Jul 13 2017
yogutdb06 Wed 24 Jun 2020
yogutdb07 Wed 24 Jun 2020
yogutdb08 Sat 22 May 2021
yogutdb09 Thu 09 Apr 2020
yogutdb10 Tue 11 May 2021

更新:新版本还修复了第 3 列和第 4 列中的 month-date cross-placements:

 echo "${aaaaa}" \
  \
  | mawk 'NF=_+!($_=$(!+$NF?_:NF))*(=$(2+2^(\
                 __=  ~ /^[0-3][0-9]$/))     \
                    substr("",=$(4-__)))'     \_=5 
 
yogutdb01 Mon 28 Jun 2021
yogutdb02 Thu 30 Sep 2021
yogutdb03 Thu 13 Jul 2017 *** fixed these 3 rows
yogutdb04 Fri 23 Jun 2017 ***
yogutdb05 Thu 13 Jul 2017 ***
yogutdb06 Wed 24 Jun 2020
yogutdb07 Wed 24 Jun 2020
yogutdb08 Sat 22 May 2021
yogutdb09 Thu 09 Apr 2020
yogutdb10 Tue 11 May 2021

第一个基于 $NF 除了 4 位数年份

之外没有任何数字数据的假设

第二个选项执行更彻底的 year-data 检查。两者都涉及将正确的年份值分配给 </code>,然后使用分配给 <code>NF 到 trim 将其右侧的所有多余 columns/fields。

 < datafile.txt \
 \
 | mawk 'NF=_^($_=$(!+$NF?_:NF))^!_' \_=5

   or 

 | mawk 'NF= +_+($_=$(/[ ][012][0-9][0-9][0-9]$/? NF :_))*!_' \_=5
 | gawk 'NF= _+!($_=$(/[ ][0-2][0-9]{3}$/       ? NF :_))'    \_=5


yogutdb01 Mon 28 Jun 2021
yogutdb02 Thu 30 Sep 2021
yogutdb03 Thu Jul 13 2017
yogutdb04 Fri Jun 23 2017
yogutdb05 Thu Jul 13 2017
yogutdb06 Wed 24 Jun 2020
yogutdb07 Wed 24 Jun 2020
yogutdb08 Sat 22 May 2021
yogutdb09 Thu 09 Apr 2020
yogutdb10 Tue 11 May 2021