我是 AWK 的新手,正在尝试使用 AWK 为另一个程序准备输入。我有如下表所示的数据,我需要从第 5 列到第 10 列中提取数据。此外,对于遇到的每个新日期(如第 1 列和第 2-4 列中所述),我需要编写前面的命令 ( DATES
),请参见下文“期望的输出”。
输入示例 (
input.txt
) -请注意,第一行注释仅用于说明目的,并不出现在实际数据中。# 1 2 3 4 5 6 7 8 9 10 20071016 16 Oct 2007 A X1 X2 X3 X4 X5 20071017 17 Oct 2007 A X1 X2 X3 X4 X5 20071017 17 Oct 2007 B X1 X2 X3 X4 X5 20071018 18 Oct 2007 C X1 X2 X3 X4 X5
期望输出 (
out.txt
)DATES 16 Oct 2007 / / WCONPROD A X1 X2 X3 X3 X4 X5 / / DATES 17 Oct 2007 / / WCONPROD A X1 X2 X3 X3 X4 X5 / / WCONPROD B X1 X2 X3 X3 X4 X5 / / DATES 18 Oct 2007 / / WCONPROD C X1 X2 X3 X3 X4 X5 / /
DATES
我遇到的问题是,如果有多行具有相同的日期,则每个日期仅打印一次。我找到并修改了以下 AWK 行以达到此目的,但我很难为每个(新)日期仅提供一次日期。我已经制作了另一列,试图让 AWK 查找/比较第一列与前一列,但不确定如何实现这一点。
awk
命令已尝试{ printf "%-s\n%-s %s %s %s\n%s\n", "DATES", $2,$3,$4,"/","/" print "\nWCONPROD\n" printf " %-s \t%s %s %s %s %s %s %s\n%s\n\n", $5, $6, $7, $8, $8, $9, $10, "/","/" }
- 如果我运行这些 AWK 命令,那么我会
DATES
打印每一行,如下所示:DATES 16 Oct 2007 / / WCONPROD A X1 X2 X3 X3 X4 X5 / / DATES 17 Oct 2007 / / WCONPROD A X1 X2 X3 X3 X4 X5 / / ## i want to remove (not to print) these/next 3 lines as this date was already declared earlier DATES 17 Oct 2007 / / WCONPROD B X1 X2 X3 X3 X4 X5 / / DATES 18 Oct 2007 / / WCONPROD C X1 X2 X3 X3 X4 X5 / /
答案1
下面的awk
程序应该可以解决这个问题:
awk '$1!=lastdate {printf "DATES\n%s %s %s /\n/\n",$2,$3,$4; lastdate=$1}
{print "WCONPROD"; for (i=5;i<=NF;i++) printf "%s%s",$i,OFS; print "/\n/"}' input.txt
这会将第一列的值与变量的内容进行比较lastdate
,如果它们不同,则打印指定的“标题”部分。它还将更新lastdate
为线上新发现的日期。
对于所有行,它将打印WCONPROD
字符串,然后是字段 5 到(无论您有多少个字段),由“输出字段分隔符”分隔(默认为单个空格,-v OFS='whatever'
可根据您的需要根据命令行参数进行更改),然后通过/ <newline> /
模式。
您的示例的输出:
DATES
16 Oct 2007 /
/
WCONPROD
A X1 X2 X3 X4 X5 /
/
DATES
17 Oct 2007 /
/
WCONPROD
A X1 X2 X3 X4 X5 /
/
WCONPROD
B X1 X2 X3 X4 X5 /
/
DATES
18 Oct 2007 /
/
WCONPROD
C X1 X2 X3 X4 X5 /
/