我有一个包含空单元格的 PSV 文件。我想用值填充空单元格00000000000
输入示例
0000000001|00346743139|201901|07
0000000002||201901|00
所需输出
0000000001|003467431|201901|07
0000000002|00000000000|201901|00
我尝试过使用
sed -i "s/||/|00000000000|/g" filename
答案1
您的sed
命令似乎正在将所有不重叠的字符串替换||
为|00000000000|
.目前尚不清楚这如何不能解决您的问题,至少对于提供的数据而言:
% sed 's/||/|00000000000|/g' file.csv
0000000001|00346743139|201901|07
0000000002|00000000000|201901|00
请注意,您的预期输出似乎被截断00346743139
为003467431
(最后两个整数被删除)。目前尚不清楚这是否是故意的。
如果在您的 Unix 上使用非标准-i
选项实现时出现问题sed
,请参阅帖子如何使用 sed -i (就地编辑)实现可移植性?
例如,在 macOS 上,您的命令将为您提供
$ sed -i "s/||/|00000000000|/g" filename
sed: 1: "filename": invalid command code f
由于该-i
选项在该系统上的使用方式不同。请-i ''
在 macOS 上使用(并man sed
在您的系统上阅读有关此选项的信息)。
为了获得更强大的 CSV 解析,您可能需要使用实际的 CSV 解析器。
使用csvkit 工具进行 CSV 解析并jq
进行实际处理:
% csvjson -I -H file.csv | jq -r '.[] | map(select(. == null) |= "00000000000") | @csv' | csvformat -D '|'
0000000001|00346743139|201901|07
0000000002|00000000000|201901|00
首先使用 .csv 文件将 CSV 文件转换为 JSON csvjson
。我们此处使用的选项关闭类型推断(以便将数字解释为字符串),并告诉实用程序 CSV 数据中没有标题行。该csvjson
工具将自动检测|
数据中使用的正确分隔符,但您也可以使用 明确告诉它|
用作分隔符-d '|'
。
然后,代码jq
将所有空值替换为字符串00000000000
,并将处理后的数据再次格式化为 CSV。
由于您想要以管道分隔的输出,csvformat
因此用于将@csv
injq
输出的分隔符更改为|
- 字符。
将输出重定向到新文件名,然后可以选择用该新文件替换原始数据。
csvkit
和均jq
适用于 macOS,通过Homebrew 包管理器。
答案2
您的sed
命令看起来不错,如果我用您的输入示例尝试它,它就会起作用。
不过,作为解析管道分隔文件或一般表格式值的通用替代方案,我建议使用awk
。看来您想用 替换“空”列00000000000
。为此,您可以使用
awk 'BEGIN{FS=OFS="|"} {for (i=1;i<=NF;i++) {if ($i=="") $i="00000000000"}} 1' filename
- 这将首先指示
awk
考虑|
输入和输出的字段分隔符(FS
是输入字段分隔符,OFS
是输出字段分隔符。 - 然后它将遍历一行的所有字段(=列),如果发现一个空字段,则将其值设置为
00000000000
($i
引用“i
当前行的字段号”,并且NF
是包含字段数量的自动生成的变量)。 - 最后,它将打印所有行,包括可能的修改(
1
最后看似杂乱的部分)
您还可以轻松地将其限制为仅适用于字段 nr。 2、如果您想以不同方式处理其他空列:
awk 'BEGIN{FS=OFS="|"} {if ($2=="") $2="00000000000"} 1' filename