英文:
I need to reformat an output file into columns
问题
cn description zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
英文:
I have a text file formatted like:
cn: ressync2gb
description: MailBox SYNC 2GB
zimbraFileMaxSize: 2147483648
zimbraId: 776bghb4396edc
zimbraQuota: 2147483648
cn: ressync3gb
description: MailBox SYNC 3GB
zimbraFileMaxSize: 2147483648
zimbraId: 22420a29
zimbraQuota: 3221225472
and I am trying to reformat the second field into columns.
What I tried
awk '{ORS=(NR%3?FS:RS); print $2}' allcos.txt | column -t
What I expect:
cn description zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
答案1
得分: 2
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
英文:
$ awk -F": " '{ORS=(NR%5?"\t":RS); print $2}' allcos.txt
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
答案2
得分: 2
gawk -F ': ' 'BEGIN { PROCINFO["sorted_in"] = "@val_num_asc" }
/cn: / { ++i } { a[$1, i] = $2 } !b[$1] { b[$1] = ++j }
END { for (j = 0; j <= i; ++j) {
for (k in b) printf "%s\t", j ? a[k, j] : k; print ""
} }' file | column -t -s $'\t'
输出:
cn 描述 zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb 邮箱同步2GB 2147483648 776bghb4396edc 2147483648
ressync3gb 邮箱同步3GB 2147483648 22420a29 3221225472
* 预期数据中一行内不会出现两个 `: ` 实例。需要使用字符串操作代替。
* 也可以排除 `PROCINFO["sorted_in"]`,使用通用的 awk,但需要将键存储在另一个索引数组变量中,代码会变得更冗长。
* 也可以使用 `RS="cn: "` 解决方案,但它要求数据格式保持一致,有点枯燥。
英文:
gawk -F ': ' 'BEGIN { PROCINFO["sorted_in"] = "@val_num_asc" }
/cn: / { ++i } { a[$1, i] = $2 } !b[$1] { b[$1] = ++j }
END { for (j = 0; j <= i; ++j) {
for (k in b) printf "%s\t", j ? a[k, j] : k; print ""
} }' file | column -t -s $'\t'
Output:
cn description zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
- This expects data to not have two instances of
:
in a line. String manipulation would need to be used instead. PROCINFO["sorted_in"]
can also be excluded and a generic awk can be used instead but it would require storing key in another indexed array variable and code becomes more verbose.- A
RS="cn: "
solution can be used instead but it expects data format to be consistent and it's boring.
答案3
得分: 0
这里有一个Ruby代码来完成这个任务:
ruby -r csv -e '
data=$<.map{|line| line.split(/:[[:blank:]]*/,2)}.
each_with_object(Hash.new {|h,k| h[k] = []}){|(k,v),h| h[k]<<v.chomp }
tbl=CSV.generate(**{:headers=>false, :col_sep=>"\t"}){ |csv|
csv<<data.keys
data.values.transpose.each{|row| csv<<row}
}
puts tbl'
输出:
cn description zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
英文:
Here is a Ruby to do that:
ruby -r csv -e '
data=$<.map{|line| line.split(/:[[:blank:]]*/,2)}.
each_with_object(Hash.new {|h,k| h[k] = []}){|(k,v),h| h[k]<<v.chomp }
tbl=CSV.generate(**{:headers=>false, :col_sep=>"\t"}){ |csv|
csv<<data.keys
data.values.transpose.each{|row| csv<<row}
}
puts tbl' file | column -t -s $'\t'
Prints:
cn description zimbraFileMaxSize zimbraId zimbraQuota
ressync2gb MailBox SYNC 2GB 2147483648 776bghb4396edc 2147483648
ressync3gb MailBox SYNC 3GB 2147483648 22420a29 3221225472
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论