如何使用 CSVKit 截断列的长度?
定义如下:
- 第一栏:无长度限制
- 第 2 列:<不超过 2 个字符>
这应该正确处理转义(引用)的列和新行。
例如:
First Header,Second Header
foo,
foo,b
foo,bar
foo,"bar"
foo,"""bar"
foo,"
bar"
应该成为
First Header,Second Header
foo,
foo,b
foo,ba
foo,ba
foo,"""b"
foo,"
b"
答案1
如同r_31415 的回答,但无需命名除我们要修改的字段之外的任何其他字段或记住字段的顺序(也类似于罗艾玛的回答在这方面):
csvsql --query 'UPDATE stdin SET "Second Header" = substr("Second Header",1,2); SELECT * FROM stdin' <file
一种稍微灵活的方法,允许我们插入任何支持 JSON 的工具来对数据进行所需的转换:
- 使用
csvjson
csvkit 创建 CSV 数据的 JSON 数组。 - 用于
jq
读取 JSON 数据,并将Second Header
值截断为两个字符。 - 使用
in2csv
csvkit 读取 JSON 并创建 CSV。
csvjson file | jq 'map(."Second Header" |= .[:2])' | in2csv -f json
考虑到问题中的 CSV 数据,的输出csvjson
相当于
[
{
"First Header": "foo",
"Second Header": null
},
{
"First Header": "foo",
"Second Header": "b"
},
{
"First Header": "foo",
"Second Header": "bar"
},
{
"First Header": "foo",
"Second Header": "bar"
},
{
"First Header": "foo",
"Second Header": "\"bar"
},
{
"First Header": "foo",
"Second Header": "\nbar"
}
]
的输出jq
将是
[
{
"First Header": "foo",
"Second Header": null
},
{
"First Header": "foo",
"Second Header": "b"
},
{
"First Header": "foo",
"Second Header": "ba"
},
{
"First Header": "foo",
"Second Header": "ba"
},
{
"First Header": "foo",
"Second Header": "\"b"
},
{
"First Header": "foo",
"Second Header": "\nb"
}
]
最终输出:
First Header,Second Header
foo,
foo,b
foo,ba
foo,ba
foo,"""b"
foo,"
b"
答案2
这是 csvsql 的解决方案:
csvsql -d ',' --query 'SELECT "First Header" as "First Header",substr("Second Header",1,2) as "Second Header" FROM data' data.txt
First Header,Second Header
foo,
foo,b
foo,ba
foo,ba
foo,"""b"
foo,"
b"