我有一个需要大量操作的csv文件。也许通过使用awk和sed?
输入:
"Sequence","Fat","Protein","Lactose","Other Solids","MUN","SCC","Batch Name"
1,4.29,3.3,4.69,5.6,11,75,"35361305a"
2,5.87,3.58,4.41,5.32,10.9,178,"35361305a"
3,4.01,3.75,4.75,5.66,12.2,35,"35361305a"
4,6.43,3.61,3.56,4.41,9.6,275,"35361305a"
最终输出:
43330075995647
59360178995344
40380035995748
64360275964436
我能够逐步完成其中的一些工作
如何测试超过9.9的特定列并将其替换为9.9?
此外,有没有办法结合任何这些步骤?
删除第一行:
tail -n +2 test.csv > test1.txt
删除逗号:
sed 's/,/ /g' test1.txt > test2.txt
删除引号:
sed 's/"//g' test2.txt > test3.txt
删除第1列和第8列以及
将剩余列重新排序为1,2,6,5,4,3:
sort test3.txt | uniq -c | awk '{print $3 "\t" $4 "\t" $8 "\t" $7 "\t" $6 "\t" $5}' test4.txt
测试新列1,2,4,5,6 - 如果值超过9.9,则将其替换为9.9
How should I do this step?
以下问题的解决方案在前一个问题中找到 - reformating a text file
第1,2,4,5,6列圆形小数到十分之一
第3列需要四个字符长,使用零到左填充
删除句号和空格
awk '{$0=sprintf("%.1f%.1f%4s%.1f%.1f%.1f", $1,$2,$3,$4,$5,$6);gsub(/ /,"0");gsub(/\./,"")}1' test5.txt > test6.txt
答案 0 :(得分:0)
三人合唱:
awk -F, '{gsub(/"/,"");$1=$1} NR>1' test.csc
1 4.29 3.3 4.69 5.6 11 75 35361305a
2 5.87 3.58 4.41 5.32 10.9 178 35361305a
3 4.01 3.75 4.75 5.66 12.2 35 35361305a
4 6.43 3.61 3.56 4.41 9.6 275 35361305a
答案 1 :(得分:0)
这将从原始文件中生成所需的输出。请注意,在您指定的问题中 - 请注意,在您指定的问题“第4列舍入到整数”但在所需的输出中,您已将其舍入到一个小数位:
awk -F'[,"]+' 'function m(x) { return x < 9.9 ? x : 9.9 }
NR > 1 {
s = sprintf("%.1f%.1f%04d%.1f%.1f%.1f", m($2),m($3),$7,m($6),m($5),m($4))
gsub(/\./, "", s)
print s
}' test.csv
我已将字段分隔符指定为任意数量的逗号和双引号,因此这将“解析”您的CSV格式,而无需任何其他步骤。
函数m
返回最小值9.9以及传递给它的数字。
输出:
43330075995647
59360178995344
40380035995748
64360275964436
答案 2 :(得分:-1)
tail -n +2 file | sort -u | awk -F , '
{
$0 = $1 FS $2 FS $6 FS $5 FS $4 FS $3
for (i = 1; i <= 6; ++i)
if ($i > 9.9)
$i = 9.9
$0 = sprintf("%.1f%.1f%4s%.0f%.1f%.1f", $1, $2, $3, $4, $5, $6)
gsub(/ /, "0"); gsub(/[.]/, "")
print
}
'
或者
< file awk -F , '
NR > 1 {
$0 = $1 FS $2 FS $6 FS $5 FS $4 FS $3
for (i = 1; i <= 6; ++i)
if ($i > 9.9)
$i = 9.9
$0 = sprintf("%.1f%.1f%4s%.0f%.1f%.1f", $1, $2, $3, $4, $5, $6)
gsub(/ /, "0"); gsub(/[.]/, "")
print
}
'
输出:
104309964733
205909954436
304009964838
406409643636