更新 CSV 文件以删除第一个数字并在特定列中插入小数位

Posted

技术标签:

【中文标题】更新 CSV 文件以删除第一个数字并在特定列中插入小数位【英文标题】:Update a CSV file to drop the first number and insert a decimal place in a particular column 【发布时间】:2021-07-22 09:54:32 【问题描述】:

我需要帮助来执行以下操作

我的 CSV 文件如下所示

900001_10459.jpg,036921,Initiated
900002_10454.jpg,027964,Initiated
900003_10440.jpg,021449,Initiated
900004_10440.jpg,016650,Initiated
900005_10440.jpg,013929,Initiated

我需要做的是生成一个新的 csv 文件,如下所示

900001_10459.jpg,3692.1,Initiated
900002_10454.jpg,2796.4,Initiated
900003_10440.jpg,2144.9,Initiated
900004_10440.jpg,1665.0,Initiated
900005_10440.jpg,1392.9,Initiated

如果我要这样做作为测试

echo '036921' | awk -v range=1 'print substr($0,range+1)' | sed 's/.$/.&/'

我明白了

3692.1

谁能帮助我,以便我可以合并它(或任何类似的东西)来更改我的 CSV 文件?

【问题讨论】:

所以可以在结果中去掉前导零吗?从表面上看:awk -F, 'BEGIN OFS = "," $2 /= 10; print; ',但在1665 之后省略了.0。这有多重要?会有多个前导零的数字吗?没有前导零?超过 6 位数? 并非所有前导零。只是最左边的零。我希望有 4 个数字(包括零)和最后一个值(第 5 个值)与 4 个值用小数点分隔。例如,像 000669 这样的数字需要更改为 0066.9 那么@Bohemian 提出的sed 解决方案是合适的——这是一个纯字符串操作问题,而不是数字问题。可以使用awk 来完成,但最终您会使用printf "%s,%06.1f,%s\n", $1, $2 / 10, $3 来打印值(并且您不执行/= 操作)。 【参考方案1】:

I wish to have 4 numbers (including zeros) and the last value (5th value) separated from the 4 values by a decimal point.

如果我理解,您不需要该字段的所有数字,而只需要最后五位数字。

使用awk,您可以使用substr 函数获取最后五位,然后使用sub() 函数打印最后一位与前4 位隔开小数点的字段:

awk -F',' -v OFS=',' '$2= substr($2, length($2) - 4, length($2) ); sub(/[[:digit:]]1$/, ".&",$2);print' file
900001_10459.jpg,3692.1,Initiated
900002_10454.jpg,2796.4,Initiated
900003_10440.jpg,2144.9,Initiated
900004_10440.jpg,1665.0,Initiated
900005_10440.jpg,1392.9,Initiated

【讨论】:

【参考方案2】:

假设带有前导零的值仅出现在第二列中,我将按照以下方式使用 GNU AWK 来完成此任务,让 file.txt 内容为

900001_10459.jpg,036921,Initiated
900002_10454.jpg,027964,Initiated
900003_10440.jpg,021449,Initiated
900004_10440.jpg,016650,Initiated
900005_10440.jpg,013929,Initiated

然后

awk 'BEGINFS=",0?";OFS=","$2=gensub(/([0-9])$/, ".\\1", 1, $2);print' file.txt

输出

900001_10459.jpg,3692.1,Initiated
900002_10454.jpg,2796.4,Initiated
900003_10440.jpg,2144.9,Initiated
900004_10440.jpg,1665.0,Initiated
900005_10440.jpg,1392.9,Initiated

说明:我将字段分隔符 (FS) 设置为 ,,可选地后跟 0,因此前导零将被丢弃作为分隔符的一部分。在第二个中,我将最后一位数字替换为 .后面跟着那个数字。最后我print这样改行,使用,作为分隔符。

(在 gawk 4.2.1 中测试)

【讨论】:

【参考方案3】:

使用awk并结合comment中指定的条件,您可以使用:

$ awk -F, ' printf "%s,%06.1f,%s\n", $1, $2 / 10, $3 ' data
900001_10459.jpg,3692.1,Initiated
900002_10454.jpg,2796.4,Initiated
900003_10440.jpg,2144.9,Initiated
900004_10440.jpg,1665.0,Initiated
900005_10440.jpg,1392.9,Initiated
$

使用提供逗号的printf 格式字符串,无需设置OFS(因为printf 不使用OFS)。

【讨论】:

【参考方案4】:

试试

sed 's/,0*([0-9]*)([0-9]),/,\1.\2,/' myfile.csv

【讨论】:

考虑到只删除一个零的要求,0 之后的* 不是必需的。甚至 GNU sed(4.2.2 测试)也需要 -E-r 来激活扩展的正则表达式; macOS sed 需要-E,不支持-r

以上是关于更新 CSV 文件以删除第一个数字并在特定列中插入小数位的主要内容,如果未能解决你的问题,请参考以下文章

如何识别列中的数字并在该数字中添加特定数字

如何对大量 csv 文件进行排序以按特定顺序读取它们?

导入 cvs 但基于特定列中的零删除行[重复]

使用条件从 CSV 文件中删除一行

如何使用 CSV(平面文件)更新 MySQL 数据库并在插入前验证数据

PySpark 通过从十进制列中删除比例来写入 csv