这个问题有几个阶段。
我有以下数据,我想首先在第 2 列、第 5 列上对其进行排序,然后在第 1 列上进行排序。然后我想将第 5 列和第 6 列与分隔符组合在一起。当值发生变化时,新的 5 和 6 之间的值将打印新数据。顶部是 5-6 的新值。
也许一个例子会有所帮助。
原始数据。
fldr cable pdu_edit stu grnd_sta chan_pdu
64 3 1 13 145 156
66 3 1 13 145 156
79 1 1 9 97 108
117 3 1 13 145 156
240 3 1 13 145 156
255 3 1 13 145 156
263 3 1 13 145 156
291 3 1 13 145 156
817 1 1 9 97 108
946 1 1 9 97 108
我希望打印时的样子:
Cable 1
97-108
79,817,946
Cable 3
145-156
64,66,117,240,255,263,291
我还没能走多远。为了对其进行排序,我使用了:
sort -k2 -k5 -k1 filename.txt
然后打印它我用的是:
awk '{if ($2==1 && $5==97) {print $1}}' filename.txt | xargs | sed -e 's/ /,/g' | sort
但在上述情况下,我选择电缆编号和我在 grnd_sta 中查找的编号。然而我对此很陌生,我想我在学会走路之前先尝试跑步。不确定如何将其组合在一起以生成像示例一样的文本文件。我在想我必须使用 if 函数,以便 grnd_sta 与电缆编号相关时发生变化。
答案1
对于 SQL 来说,这似乎是一项简单的任务。
csv
+ sql
==csvsql
来自csvkit
!
您可以通过 pip 安装它。
在开始之前,您可能需要在执行此操作之前修复文件:删除空行和每行末尾的空格:
sed -i.bak '2d;s/[[:blank:]]*$//' file
你可以半途而废:
csvsql \
-d' ' -S \
--query 'select cable,grnd_sta || "-" || chan_pdu,group_concat(fldr) from file group by cable' \
file \
| csvformat -D' '
- 如果您的文件是制表符分隔的,您可能需要
-t
而不是。-d' '
- 用于
csvformat -D' '
获取以空格分隔的输出,因为csvsql
仅输出以逗号分隔的输出。处理起来更容易awk
,但 csvsql 会在最后一列周围加上引号,我们不希望这样!
输出:
cable "grnd_sta || ""-"" || chan_pdu" group_concat(fldr)
1 97-108 79,817,946
3 145-156 64,66,117,240,255,263,291
从这里您可以继续使用awk
:
... \
| awk 'NR>1{printf "Cable %s\n\n%s\n%s\n\n",$1,$2,$3}' \
| head -n-1
输出:
Cable 1
97-108
79,817,946
Cable 3
145-156
64,66,117,240,255,263,291
答案2
我建议使用包含所有必要计算的 Awk 脚本:
NR==1 { next }
NF==0 { next }
{ a[$2][1]= $5 "-" $6;
a[$2][2]= a[$2][2] $1 "," ; }
END { for (c in a) printf "Channel %d\n%s\n%s\n\n",c,a[c][1],a[c][2] }
用法:
$awk -f x.awk data
Channel 1
97-108
79,817,946,
Channel 3
145-156
64,66,117,240,255,263,291,