我正在尝试使用 awk 来旋转文件。这是我的输入文件的示例:
VarName;TimeString;VarValue;Validity;Time_ms
A;23.11.201215:03:53;1;1;41236627696,7593
C;23.11.201215:03:53;2;1;41236627696,7593
D;23.11.201215:03:53;3;1;41236627696,7593
A;23.11.201215:04:53;31;1;41236628391,2037
B;23.11.201215:04:53;12;1;41236628391,2037
C;23.11.201215:04:53;1;1;41236628391,2037
D;23.11.201215:05:53;8;1;41236629097,2222
B;23.11.201215:05:53;7;1;41236629097,2222
C;23.11.201215:05:53;15;1;41236629097,2222
这是我想要的输出:
TimeString;Time_ms;A;B;C;D
23.11.201215:03:53;41236627696,7593;1;;2;3
23.11.201215:04:53;41236628391,2037;31;12;1;
23.11.201215:05:53;41236629097,2222;;7;15;8
获得此结果的最佳方法是什么?
使用@steve编写的脚本解决
答案1
这是使用的一种方法gawk
。运行如下:
awk -f script.awk file
内容script.awk
:
BEGIN {
FS=OFS=";"
}
NR==1 {
r = $2 FS $5
next
}
{
!x[$1]
a[$2,$5][$1]=$3
}
END {
m = asorti(x,y)
for (k=1;k<=m;k++) {
r = r FS y[k]
}
print r
n = asorti(a,b)
for (i=1;i<=n;i++) {
for (j=1;j<=m;j++) {
for (k in a[b[i]]) {
if (k == y[j]) {
var = a[b[i]][k]
}
}
line = line FS var
var = ""
}
sub(SUBSEP, FS, b[i])
print b[i] line
line = ""
}
}
或者,这是一个衬里:
awk 'BEGIN { FS=OFS=";" } NR==1 { r = $2 FS $5; next } { !x[$1]; a[$2,$5][$1]=$3 } END { m = asorti(x,y); for (k=1;k<=m;k++) { r = r FS y[k] } print r; n = asorti(a,b); for (i=1;i<=n;i++) { for (j=1;j<=m;j++) { for (k in a[b[i]]) { if (k == y[j]) { var = a[b[i]][k] } } line = line FS var; var = "" } sub(SUBSEP, FS, b[i]); print b[i] line; line = "" } }' file
结果:
TimeString;Time_ms;A;B;C;D
23.11.201215:03:53;41236627696,7593;1;;2;3
23.11.201215:04:53;41236628391,2037;31;12;1;
23.11.201215:05:53;41236629097,2222;;7;15;8
您需要dos2unix
先运行您的文件。 IE:
dos2unix Flussi0.csv
或者,将记录分隔符更改为 ,\r\n
以便awk
了解 Windows 换行符结尾是什么样的。您可以在BEGIN
块中执行此操作:
BEGIN {
FS=OFS=";"
RS="\r\n"
}
输入文件的结果发布在下面的评论中:
"TimeString";"Time_ms";"FIT01";"FIT02";"FIT03";"FIT04";"FIT05";"FIT06"
"22.06.2012 09:31:33";41082396909,7222;1,157408E-02;5,787041E-03;2,507718E-02;2,89352E-03;2,314816E-02;5,787035E-04
"22.06.2012 09:32:34";41082397615,7407;1,157408E-02;5,787041E-03;2,314816E-02;2,89352E-03;2,713479E-02;5,787035E-04
"22.06.2012 09:33:35";41082398321,7593;1,157408E-02;5,787041E-03;2,314816E-02;2,89352E-03;2,314816E-02;5,787035E-04
"22.06.2012 09:34:35";41082399016,2037;1,157408E-02;5,787041E-03;2,314816E-02;2,89352E-03;2,535274E-02;5,787035E-04
"22.06.2012 09:35:36";41082399722,2222;;;;;2,314816E-02;
答案2
最好的办法?我不知道。这是A方式。我假设代码实际上并不需要查看输入数据的标题行,并且可以只对TimeString;Time_ms;
.
(line > /dev/null; sort) < input_file > tmp0 # Discard the header line; sort the data.
# Here lies the basic pivot:
awk -F";" '
{
print $1 > "tmp1"
print $2 > "tmp2"
print $5 > "tmp5"
}' tmp0
echo "TimeString;Time_ms;\c"
tr "\n" ";" < tmp1; echo
tr "\n" ";" < tmp2; echo
tr "\n" ";" < tmp5; echo
这将以分号 ( ;
) 结束输出的每一行。目前还不清楚你是否想要这样。如果你不想要它,你也许可以找到一种方法来消除它。
答案3
使用reshape
子命令磨坊主(mlr
,一个支持 CSV 的工具),然后是unsparsify
:
$ mlr --csv --fs ';' reshape -s VarName,VarValue then unsparsify file
TimeString;Validity;Time_ms;A;C;D;B
23.11.201215:03:53;1;41236627696,7593;1;2;3;
23.11.201215:04:53;1;41236628391,2037;31;1;;12
23.11.201215:05:53;1;41236629097,2222;;15;8;7
-s
子命令的选项采用reshape
逗号分隔的对,由键字段名称和值字段名称组成。然后,它执行长到宽的主元操作,使用值字段中的数据在键字段中创建字段。
unsparsify
需要在没有所有字段的记录中添加空字段的操作。
要以正确的顺序重新排列最后四个字段并删除该Validity
字段:
$ mlr --csv --fs ';' reshape -s VarName,VarValue then unsparsify then reorder -e -f A,B,C,D then cut -x -f Validity file
TimeString;Time_ms;A;B;C;D
23.11.201215:03:53;41236627696,7593;1;;2;3
23.11.201215:04:53;41236628391,2037;31;12;1;
23.11.201215:05:53;41236629097,2222;;7;15;8
或者,更短地仅使用cut
子命令来重新排列和选择输出字段:
$ mlr --csv --fs ';' reshape -s VarName,VarValue then unsparsify then cut -o -f TimeString,Time_ms,A,B,C,D file
TimeString;Time_ms;A;B;C;D
23.11.201215:03:53;41236627696,7593;1;;2;3
23.11.201215:04:53;41236628391,2037;31;12;1;
23.11.201215:05:53;41236629097,2222;;7;15;8
一般情况下,我们可能不知道新生成的字段的名称,因此我们可能希望按名称对字段进行排序,删除该Validity
字段,然后将两个时间字段放在前面,而不按名称提及新字段:
$ mlr --csv --fs ';' reshape -s VarName,VarValue then unsparsify then sort-within-records then cut -x -f Validity then reorder -f TimeString,Time_ms file
TimeString;Time_ms;A;B;C;D
23.11.201215:03:53;41236627696,7593;1;;2;3
23.11.201215:04:53;41236628391,2037;31;12;1;
23.11.201215:05:53;41236629097,2222;;7;15;8