更新 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 文件以删除第一个数字并在特定列中插入小数位的主要内容,如果未能解决你的问题,请参考以下文章