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
我再次需要你的专业知识,我正在尝试使用 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