如何使用awk提取混合/部分缺席的记录到定义的顺序



我有以下数据(它还包含其他行,这里是一个有意义的摘录):

group
bb 1
cc 1
dd 1
end
group
dd 2
bb 2
end
group
aa 3
end

我不知道值(如"1", "2",等等),必须匹配的名称(通用"组", ";我想得到的数据过滤和排序按以下顺序(与空制表符时,字符串不存在):

group       bb 1    cc 1    dd 1
group       bb 2            dd 2
group   aa 3            

我运行:

awk 'BEGIN {ORS = "t"}
/^group/ {print "n" $0}; 
/^aa/ {AA = $0}; 
/^bb/ {BB = $0}; 
/^cc/ {CC = $0}; 
/^dd/ {DD = $0}; 
/^end/ {print AA; print BB; print CC; print DD}' test.txt

group       bb 1    cc 1    dd 1
group       bb 2    **cc 1**    dd 2
group   aa 3    **bb 2**    **cc 1**    **dd 2**

的顺序是正确的,但是数据是错误的(用星号标记)。做这种过滤的正确方法是什么?谢谢!

假设:

  • 输入行不以空格开头
  • 每个^group有一个匹配的^end
  • 文件的第一行是^group
  • 文件的最后一行是^end
  • ^end和下一个^group之间没有行(可以忽略)

主要问题是,每次看到group时,我们都需要清除/重置其他变量,否则我们会延续之前group的值。

其他(次要)问题:

  • ORSvsOFS
  • 多个print命令vs单个print命令
  • 不需要行延续字符()

更新awk脚本的一个想法:

awk '
BEGIN    { OFS="t" }
/^group/ { AA=BB=CC=DD="" ; next }
/^aa/    { AA=$0          ; next }
/^bb/    { BB=$0          ; next }
/^cc/    { CC=$0          ; next }
/^dd/    { DD=$0          ; next }
/^end/   { print "group",AA,BB,CC,DD }
' test.txt

注意:; next子句是可选的,包含它是作为一个视觉提醒,我们不需要担心脚本的其余部分(对于当前行)

由此产生:

group           bb 1    cc 1    dd 1
group           bb 2            dd 2
group   aa 3

这里有一个更简单的awk解决方案:

awk '/^group$/{delete m; next} {m[$1]=$0} /^end$/{
printf "groupt%st%st%st%sn", m["aa"], m["bb"], m["cc"], m["dd"]
}' file
group         bb 1   cc 1   dd 1
group         bb 2          dd 2
group   aa 3

使用GNUawk尝试以下代码。书面和测试仅显示样品。简单的解释是,将RS设置为endn(可选),然后简单地用空格替换新行并打印该行。

awk -v RS='endn?' 'RT{gsub(/n/,OFS);print}' Input_file

如果您想要以制表符分隔输出,请尝试以下操作:

awk -v RS='endn?' -v OFS="t" 'RT{gsub(/n/,OFS);print}' Input_file

相关内容

  • 没有找到相关文章

最新更新